1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package com.android.server.pm;
17 
18 import static android.Manifest.permission.DELETE_PACKAGES;
19 import static android.Manifest.permission.INSTALL_PACKAGES;
20 import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
21 import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
22 import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
23 import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
24 import static android.app.AppOpsManager.MODE_DEFAULT;
25 import static android.app.AppOpsManager.MODE_IGNORED;
26 import static android.content.Intent.ACTION_MAIN;
27 import static android.content.Intent.CATEGORY_DEFAULT;
28 import static android.content.Intent.CATEGORY_HOME;
29 import static android.content.Intent.EXTRA_LONG_VERSION_CODE;
30 import static android.content.Intent.EXTRA_PACKAGE_NAME;
31 import static android.content.Intent.EXTRA_VERSION_CODE;
32 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
33 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
34 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
35 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
36 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
37 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
38 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
39 import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
40 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
41 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
42 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
43 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
44 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
45 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_PERMISSION_GROUP;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
53 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
54 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
55 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
56 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
57 import static android.content.pm.PackageManager.INSTALL_FAILED_PROCESS_NOT_DEFINED;
58 import static android.content.pm.PackageManager.INSTALL_FAILED_SESSION_INVALID;
59 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
60 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
61 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
62 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
63 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
64 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
65 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
66 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
67 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
68 import static android.content.pm.PackageManager.INSTALL_STAGED;
69 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
70 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
71 import static android.content.pm.PackageManager.MATCH_ALL;
72 import static android.content.pm.PackageManager.MATCH_ANY_USER;
73 import static android.content.pm.PackageManager.MATCH_APEX;
74 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
75 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
76 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
77 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
78 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
79 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
80 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
81 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
82 import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
83 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
84 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
85 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
86 import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
87 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
88 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
89 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
90 import static android.content.pm.PackageManager.RESTRICTION_NONE;
91 import static android.content.pm.PackageManager.TYPE_ACTIVITY;
92 import static android.content.pm.PackageManager.TYPE_PROVIDER;
93 import static android.content.pm.PackageManager.TYPE_RECEIVER;
94 import static android.content.pm.PackageManager.TYPE_SERVICE;
95 import static android.content.pm.PackageManager.TYPE_UNKNOWN;
96 import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
97 import static android.content.pm.PackageManagerInternal.LAST_KNOWN_PACKAGE;
98 import static android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
99 import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile;
100 import static android.os.PowerWhitelistManager.REASON_LOCKED_BOOT_COMPLETED;
101 import static android.os.PowerWhitelistManager.REASON_PACKAGE_REPLACED;
102 import static android.os.PowerWhitelistManager.REASON_PACKAGE_VERIFIER;
103 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
104 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
105 import static android.os.incremental.IncrementalManager.isIncrementalPath;
106 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
107 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
108 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
109 import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
110 
111 import static com.android.internal.annotations.VisibleForTesting.Visibility;
112 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
113 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
114 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
115 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME;
116 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME;
117 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME;
118 import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
119 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
120 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
121 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
122 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
123 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
124 import static com.android.server.pm.PackageManagerServiceUtils.comparePackageSignatures;
125 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
126 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
127 import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
128 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
129 import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
130 import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
131 import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
132 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
133 import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
134 import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
135 
136 import android.Manifest;
137 import android.annotation.AppIdInt;
138 import android.annotation.IntDef;
139 import android.annotation.NonNull;
140 import android.annotation.Nullable;
141 import android.annotation.StringRes;
142 import android.annotation.UserIdInt;
143 import android.annotation.WorkerThread;
144 import android.app.ActivityManager;
145 import android.app.ActivityManagerInternal;
146 import android.app.AppOpsManager;
147 import android.app.ApplicationPackageManager;
148 import android.app.BroadcastOptions;
149 import android.app.IActivityManager;
150 import android.app.ResourcesManager;
151 import android.app.admin.IDevicePolicyManager;
152 import android.app.admin.SecurityLog;
153 import android.app.backup.IBackupManager;
154 import android.app.role.RoleManager;
155 import android.compat.annotation.ChangeId;
156 import android.compat.annotation.EnabledAfter;
157 import android.content.BroadcastReceiver;
158 import android.content.ComponentName;
159 import android.content.ContentResolver;
160 import android.content.Context;
161 import android.content.IIntentReceiver;
162 import android.content.Intent;
163 import android.content.IntentFilter;
164 import android.content.IntentSender;
165 import android.content.IntentSender.SendIntentException;
166 import android.content.PermissionChecker;
167 import android.content.pm.ActivityInfo;
168 import android.content.pm.ApplicationInfo;
169 import android.content.pm.AuxiliaryResolveInfo;
170 import android.content.pm.ChangedPackages;
171 import android.content.pm.Checksum;
172 import android.content.pm.ComponentInfo;
173 import android.content.pm.DataLoaderType;
174 import android.content.pm.FallbackCategoryProvider;
175 import android.content.pm.FeatureInfo;
176 import android.content.pm.IDexModuleRegisterCallback;
177 import android.content.pm.IOnChecksumsReadyListener;
178 import android.content.pm.IPackageChangeObserver;
179 import android.content.pm.IPackageDataObserver;
180 import android.content.pm.IPackageDeleteObserver;
181 import android.content.pm.IPackageDeleteObserver2;
182 import android.content.pm.IPackageInstallObserver2;
183 import android.content.pm.IPackageInstaller;
184 import android.content.pm.IPackageLoadingProgressCallback;
185 import android.content.pm.IPackageManager;
186 import android.content.pm.IPackageManagerNative;
187 import android.content.pm.IPackageMoveObserver;
188 import android.content.pm.IPackageStatsObserver;
189 import android.content.pm.IncrementalStatesInfo;
190 import android.content.pm.InstallSourceInfo;
191 import android.content.pm.InstantAppInfo;
192 import android.content.pm.InstantAppRequest;
193 import android.content.pm.InstantAppResolveInfo.InstantAppDigest;
194 import android.content.pm.InstrumentationInfo;
195 import android.content.pm.IntentFilterVerificationInfo;
196 import android.content.pm.KeySet;
197 import android.content.pm.ModuleInfo;
198 import android.content.pm.PackageChangeEvent;
199 import android.content.pm.PackageInfo;
200 import android.content.pm.PackageInfoLite;
201 import android.content.pm.PackageInstaller;
202 import android.content.pm.PackageManager;
203 import android.content.pm.PackageManager.ComponentType;
204 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
205 import android.content.pm.PackageManager.ModuleInfoFlags;
206 import android.content.pm.PackageManager.Property;
207 import android.content.pm.PackageManager.PropertyLocation;
208 import android.content.pm.PackageManagerInternal;
209 import android.content.pm.PackageManagerInternal.PackageListObserver;
210 import android.content.pm.PackageManagerInternal.PrivateResolveFlags;
211 import android.content.pm.PackageParser;
212 import android.content.pm.PackageParser.PackageParserException;
213 import android.content.pm.PackageParser.SigningDetails;
214 import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
215 import android.content.pm.PackagePartitions;
216 import android.content.pm.PackagePartitions.SystemPartition;
217 import android.content.pm.PackageStats;
218 import android.content.pm.PackageUserState;
219 import android.content.pm.ParceledListSlice;
220 import android.content.pm.PermissionGroupInfo;
221 import android.content.pm.PermissionInfo;
222 import android.content.pm.ProcessInfo;
223 import android.content.pm.ProviderInfo;
224 import android.content.pm.ResolveInfo;
225 import android.content.pm.SELinuxUtil;
226 import android.content.pm.ServiceInfo;
227 import android.content.pm.SharedLibraryInfo;
228 import android.content.pm.Signature;
229 import android.content.pm.SigningInfo;
230 import android.content.pm.SuspendDialogInfo;
231 import android.content.pm.TestUtilityService;
232 import android.content.pm.UserInfo;
233 import android.content.pm.VerifierDeviceIdentity;
234 import android.content.pm.VerifierInfo;
235 import android.content.pm.VersionedPackage;
236 import android.content.pm.dex.ArtManager;
237 import android.content.pm.dex.DexMetadataHelper;
238 import android.content.pm.dex.IArtManager;
239 import android.content.pm.overlay.OverlayPaths;
240 import android.content.pm.parsing.ApkLiteParseUtils;
241 import android.content.pm.parsing.PackageLite;
242 import android.content.pm.parsing.ParsingPackageUtils;
243 import android.content.pm.parsing.ParsingPackageUtils.ParseFlags;
244 import android.content.pm.parsing.component.ParsedActivity;
245 import android.content.pm.parsing.component.ParsedInstrumentation;
246 import android.content.pm.parsing.component.ParsedMainComponent;
247 import android.content.pm.parsing.component.ParsedPermission;
248 import android.content.pm.parsing.component.ParsedPermissionGroup;
249 import android.content.pm.parsing.component.ParsedProcess;
250 import android.content.pm.parsing.component.ParsedProvider;
251 import android.content.pm.parsing.component.ParsedService;
252 import android.content.pm.parsing.result.ParseResult;
253 import android.content.pm.parsing.result.ParseTypeImpl;
254 import android.content.res.Resources;
255 import android.database.ContentObserver;
256 import android.graphics.Bitmap;
257 import android.hardware.display.DisplayManager;
258 import android.net.Uri;
259 import android.os.Binder;
260 import android.os.Build;
261 import android.os.Bundle;
262 import android.os.Environment;
263 import android.os.FileUtils;
264 import android.os.Handler;
265 import android.os.HandlerExecutor;
266 import android.os.HandlerThread;
267 import android.os.IBinder;
268 import android.os.Looper;
269 import android.os.Message;
270 import android.os.Parcel;
271 import android.os.ParcelableException;
272 import android.os.PatternMatcher;
273 import android.os.PersistableBundle;
274 import android.os.PowerWhitelistManager;
275 import android.os.Process;
276 import android.os.RemoteCallbackList;
277 import android.os.RemoteException;
278 import android.os.ResultReceiver;
279 import android.os.SELinux;
280 import android.os.ServiceManager;
281 import android.os.ShellCallback;
282 import android.os.SystemClock;
283 import android.os.SystemProperties;
284 import android.os.Trace;
285 import android.os.UserHandle;
286 import android.os.UserManager;
287 import android.os.incremental.IncrementalManager;
288 import android.os.incremental.IncrementalStorage;
289 import android.os.incremental.PerUidReadTimeouts;
290 import android.os.storage.DiskInfo;
291 import android.os.storage.IStorageManager;
292 import android.os.storage.StorageEventListener;
293 import android.os.storage.StorageManager;
294 import android.os.storage.StorageManagerInternal;
295 import android.os.storage.VolumeInfo;
296 import android.os.storage.VolumeRecord;
297 import android.permission.PermissionManager;
298 import android.provider.ContactsContract;
299 import android.provider.DeviceConfig;
300 import android.provider.Settings.Global;
301 import android.provider.Settings.Secure;
302 import android.security.KeyStore;
303 import android.security.SystemKeyStore;
304 import android.service.pm.PackageServiceDumpProto;
305 import android.stats.storage.StorageEnums;
306 import android.system.ErrnoException;
307 import android.system.Os;
308 import android.text.TextUtils;
309 import android.text.format.DateUtils;
310 import android.util.ArrayMap;
311 import android.util.ArraySet;
312 import android.util.Base64;
313 import android.util.DisplayMetrics;
314 import android.util.EventLog;
315 import android.util.ExceptionUtils;
316 import android.util.IntArray;
317 import android.util.Log;
318 import android.util.LogPrinter;
319 import android.util.LongSparseLongArray;
320 import android.util.MathUtils;
321 import android.util.PackageUtils;
322 import android.util.Pair;
323 import android.util.PrintStreamPrinter;
324 import android.util.Slog;
325 import android.util.SparseArray;
326 import android.util.SparseBooleanArray;
327 import android.util.SparseIntArray;
328 import android.util.TimingsTraceLog;
329 import android.util.TypedXmlPullParser;
330 import android.util.TypedXmlSerializer;
331 import android.util.Xml;
332 import android.util.apk.ApkSignatureVerifier;
333 import android.util.jar.StrictJarFile;
334 import android.util.proto.ProtoOutputStream;
335 import android.view.Display;
336 
337 import com.android.internal.R;
338 import com.android.internal.annotations.GuardedBy;
339 import com.android.internal.annotations.VisibleForTesting;
340 import com.android.internal.app.ResolverActivity;
341 import com.android.internal.content.F2fsUtils;
342 import com.android.internal.content.NativeLibraryHelper;
343 import com.android.internal.content.PackageHelper;
344 import com.android.internal.content.om.OverlayConfig;
345 import com.android.internal.logging.MetricsLogger;
346 import com.android.internal.os.SomeArgs;
347 import com.android.internal.policy.AttributeCache;
348 import com.android.internal.security.VerityUtils;
349 import com.android.internal.telephony.CarrierAppUtils;
350 import com.android.internal.util.ArrayUtils;
351 import com.android.internal.util.CollectionUtils;
352 import com.android.internal.util.ConcurrentUtils;
353 import com.android.internal.util.DumpUtils;
354 import com.android.internal.util.FrameworkStatsLog;
355 import com.android.internal.util.FunctionalUtils;
356 import com.android.internal.util.IndentingPrintWriter;
357 import com.android.internal.util.Preconditions;
358 import com.android.permission.persistence.RuntimePermissionsPersistence;
359 import com.android.server.DeviceIdleInternal;
360 import com.android.server.EventLogTags;
361 import com.android.server.FgThread;
362 import com.android.server.LocalServices;
363 import com.android.server.LockGuard;
364 import com.android.server.PackageWatchdog;
365 import com.android.server.ServiceThread;
366 import com.android.server.SystemConfig;
367 import com.android.server.SystemServerInitThreadPool;
368 import com.android.server.Watchdog;
369 import com.android.server.apphibernation.AppHibernationManagerInternal;
370 import com.android.server.compat.CompatChange;
371 import com.android.server.compat.PlatformCompat;
372 import com.android.server.net.NetworkPolicyManagerInternal;
373 import com.android.server.pm.Installer.InstallerException;
374 import com.android.server.pm.Settings.DatabaseVersion;
375 import com.android.server.pm.Settings.VersionInfo;
376 import com.android.server.pm.dex.ArtManagerService;
377 import com.android.server.pm.dex.ArtUtils;
378 import com.android.server.pm.dex.DexManager;
379 import com.android.server.pm.dex.DexoptOptions;
380 import com.android.server.pm.dex.PackageDexUsage;
381 import com.android.server.pm.dex.ViewCompiler;
382 import com.android.server.pm.parsing.PackageCacher;
383 import com.android.server.pm.parsing.PackageInfoUtils;
384 import com.android.server.pm.parsing.PackageParser2;
385 import com.android.server.pm.parsing.library.PackageBackwardCompatibility;
386 import com.android.server.pm.parsing.pkg.AndroidPackage;
387 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
388 import com.android.server.pm.parsing.pkg.PackageImpl;
389 import com.android.server.pm.parsing.pkg.ParsedPackage;
390 import com.android.server.pm.permission.LegacyPermissionManagerInternal;
391 import com.android.server.pm.permission.LegacyPermissionManagerService;
392 import com.android.server.pm.permission.Permission;
393 import com.android.server.pm.permission.PermissionManagerService;
394 import com.android.server.pm.permission.PermissionManagerServiceInternal;
395 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
396 import com.android.server.pm.verify.domain.DomainVerificationService;
397 import com.android.server.pm.verify.domain.DomainVerificationUtils;
398 import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy;
399 import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV1;
400 import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV2;
401 import com.android.server.rollback.RollbackManagerInternal;
402 import com.android.server.storage.DeviceStorageMonitorInternal;
403 import com.android.server.uri.UriGrantsManagerInternal;
404 import com.android.server.utils.SnapshotCache;
405 import com.android.server.utils.TimingsTraceAndSlog;
406 import com.android.server.utils.Watchable;
407 import com.android.server.utils.Watched;
408 import com.android.server.utils.WatchedArrayMap;
409 import com.android.server.utils.WatchedLongSparseArray;
410 import com.android.server.utils.WatchedSparseBooleanArray;
411 import com.android.server.utils.WatchedSparseIntArray;
412 import com.android.server.utils.Watcher;
413 import com.android.server.wm.ActivityTaskManagerInternal;
414 
415 import dalvik.system.CloseGuard;
416 import dalvik.system.VMRuntime;
417 
418 import libcore.io.IoUtils;
419 import libcore.util.EmptyArray;
420 import libcore.util.HexEncoding;
421 
422 import org.xmlpull.v1.XmlPullParser;
423 import org.xmlpull.v1.XmlPullParserException;
424 
425 import java.io.BufferedOutputStream;
426 import java.io.ByteArrayInputStream;
427 import java.io.ByteArrayOutputStream;
428 import java.io.File;
429 import java.io.FileDescriptor;
430 import java.io.FileInputStream;
431 import java.io.FileOutputStream;
432 import java.io.IOException;
433 import java.io.InputStream;
434 import java.io.PrintWriter;
435 import java.lang.annotation.ElementType;
436 import java.lang.annotation.Retention;
437 import java.lang.annotation.RetentionPolicy;
438 import java.lang.annotation.Target;
439 import java.nio.charset.StandardCharsets;
440 import java.security.DigestException;
441 import java.security.DigestInputStream;
442 import java.security.MessageDigest;
443 import java.security.NoSuchAlgorithmException;
444 import java.security.PublicKey;
445 import java.security.SecureRandom;
446 import java.security.cert.Certificate;
447 import java.security.cert.CertificateException;
448 import java.security.cert.CertificateFactory;
449 import java.security.cert.X509Certificate;
450 import java.util.ArrayList;
451 import java.util.Arrays;
452 import java.util.Collection;
453 import java.util.Collections;
454 import java.util.Comparator;
455 import java.util.HashMap;
456 import java.util.HashSet;
457 import java.util.Iterator;
458 import java.util.LinkedHashSet;
459 import java.util.List;
460 import java.util.Map;
461 import java.util.Objects;
462 import java.util.Set;
463 import java.util.UUID;
464 import java.util.concurrent.CompletableFuture;
465 import java.util.concurrent.CountDownLatch;
466 import java.util.concurrent.Executor;
467 import java.util.concurrent.ExecutorService;
468 import java.util.concurrent.Future;
469 import java.util.concurrent.TimeUnit;
470 import java.util.concurrent.atomic.AtomicBoolean;
471 import java.util.concurrent.atomic.AtomicInteger;
472 import java.util.function.BiConsumer;
473 import java.util.function.Consumer;
474 import java.util.function.Function;
475 import java.util.function.Predicate;
476 
477 /**
478  * Keep track of all those APKs everywhere.
479  * <p>
480  * Internally there are three important locks:
481  * <ul>
482  * <li>{@link #mLock} is used to guard all in-memory parsed package details
483  * and other related state. It is a fine-grained lock that should only be held
484  * momentarily, as it's one of the most contended locks in the system.
485  * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
486  * operations typically involve heavy lifting of application data on disk. Since
487  * {@code installd} is single-threaded, and it's operations can often be slow,
488  * this lock should never be acquired while already holding {@link #mLock}.
489  * Conversely, it's safe to acquire {@link #mLock} momentarily while already
490  * holding {@link #mInstallLock}.
491  * <li>{@link #mSnapshotLock} is used to guard access to two snapshot fields: the snapshot
492  * itself and the snapshot invalidation flag.  This lock should never be acquired while
493  * already holding {@link #mLock}. Conversely, it's safe to acquire {@link #mLock}
494  * momentarily while already holding {@link #mSnapshotLock}.
495  * </ul>
496  * Many internal methods rely on the caller to hold the appropriate locks, and
497  * this contract is expressed through method name suffixes:
498  * <ul>
499  * <li>fooLI(): the caller must hold {@link #mInstallLock}
500  * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
501  * being modified must be frozen
502  * <li>fooLPr(): the caller must hold {@link #mLock} for reading
503  * <li>fooLPw(): the caller must hold {@link #mLock} for writing
504  * </ul>
505  * {@link #mSnapshotLock} is taken in exactly one place - {@code snapshotComputer()}.  It
506  * should not be taken anywhere else or used for any other purpose.
507  * <p>
508  * Because this class is very central to the platform's security; please run all
509  * CTS and unit tests whenever making modifications:
510  *
511  * <pre>
512  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
513  * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
514  * </pre>
515  */
516 public class PackageManagerService extends IPackageManager.Stub
517         implements PackageSender, TestUtilityService {
518     static final String TAG = "PackageManager";
519     public static final boolean DEBUG_SETTINGS = false;
520     static final boolean DEBUG_PREFERRED = false;
521     static final boolean DEBUG_UPGRADE = false;
522     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
523     private static final boolean DEBUG_BACKUP = false;
524     public static final boolean DEBUG_INSTALL = false;
525     public static final boolean DEBUG_REMOVE = false;
526     private static final boolean DEBUG_BROADCASTS = false;
527     private static final boolean DEBUG_PACKAGE_INFO = false;
528     private static final boolean DEBUG_INTENT_MATCHING = false;
529     public static final boolean DEBUG_PACKAGE_SCANNING = false;
530     private static final boolean DEBUG_VERIFY = false;
531     public static final boolean DEBUG_PERMISSIONS = false;
532     private static final boolean DEBUG_SHARED_LIBRARIES = false;
533     public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
534     public static final boolean TRACE_SNAPSHOTS = false;
535     private static final boolean DEBUG_PER_UID_READ_TIMEOUTS = false;
536 
537     // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
538     // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
539     // user, but by default initialize to this.
540     public static final boolean DEBUG_DEXOPT = false;
541 
542     static final boolean DEBUG_ABI_SELECTION = false;
543     private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
544     private static final boolean DEBUG_APP_DATA = false;
545 
546     /** REMOVE. According to Svet, this was only used to reset permissions during development. */
547     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
548 
549     private static final boolean HIDE_EPHEMERAL_APIS = false;
550 
551     private static final String PRECOMPILE_LAYOUTS = "pm.precompile_layouts";
552 
553     private static final int RADIO_UID = Process.PHONE_UID;
554     private static final int LOG_UID = Process.LOG_UID;
555     private static final int NFC_UID = Process.NFC_UID;
556     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
557     private static final int SHELL_UID = Process.SHELL_UID;
558     private static final int SE_UID = Process.SE_UID;
559     private static final int NETWORKSTACK_UID = Process.NETWORK_STACK_UID;
560     private static final int UWB_UID = Process.UWB_UID;
561 
562     static final int SCAN_NO_DEX = 1 << 0;
563     static final int SCAN_UPDATE_SIGNATURE = 1 << 1;
564     static final int SCAN_NEW_INSTALL = 1 << 2;
565     static final int SCAN_UPDATE_TIME = 1 << 3;
566     static final int SCAN_BOOTING = 1 << 4;
567     static final int SCAN_REQUIRE_KNOWN = 1 << 7;
568     static final int SCAN_MOVE = 1 << 8;
569     static final int SCAN_INITIAL = 1 << 9;
570     static final int SCAN_DONT_KILL_APP = 1 << 10;
571     static final int SCAN_IGNORE_FROZEN = 1 << 11;
572     static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1 << 12;
573     static final int SCAN_AS_INSTANT_APP = 1 << 13;
574     static final int SCAN_AS_FULL_APP = 1 << 14;
575     static final int SCAN_AS_VIRTUAL_PRELOAD = 1 << 15;
576     static final int SCAN_AS_SYSTEM = 1 << 16;
577     static final int SCAN_AS_PRIVILEGED = 1 << 17;
578     static final int SCAN_AS_OEM = 1 << 18;
579     static final int SCAN_AS_VENDOR = 1 << 19;
580     static final int SCAN_AS_PRODUCT = 1 << 20;
581     static final int SCAN_AS_SYSTEM_EXT = 1 << 21;
582     static final int SCAN_AS_ODM = 1 << 22;
583     static final int SCAN_AS_APK_IN_APEX = 1 << 23;
584 
585     @IntDef(flag = true, prefix = { "SCAN_" }, value = {
586             SCAN_NO_DEX,
587             SCAN_UPDATE_SIGNATURE,
588             SCAN_NEW_INSTALL,
589             SCAN_UPDATE_TIME,
590             SCAN_BOOTING,
591             SCAN_REQUIRE_KNOWN,
592             SCAN_MOVE,
593             SCAN_INITIAL,
594             SCAN_DONT_KILL_APP,
595             SCAN_IGNORE_FROZEN,
596             SCAN_FIRST_BOOT_OR_UPGRADE,
597             SCAN_AS_INSTANT_APP,
598             SCAN_AS_FULL_APP,
599             SCAN_AS_VIRTUAL_PRELOAD,
600     })
601     @Retention(RetentionPolicy.SOURCE)
602     public @interface ScanFlags {}
603 
604     /**
605      * Used as the result code of the {@link #getPackageStartability}.
606      */
607     @IntDef(value = {
608         PACKAGE_STARTABILITY_OK,
609         PACKAGE_STARTABILITY_NOT_FOUND,
610         PACKAGE_STARTABILITY_NOT_SYSTEM,
611         PACKAGE_STARTABILITY_FROZEN,
612         PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED,
613     })
614     @Retention(RetentionPolicy.SOURCE)
615     public @interface PackageStartability {}
616 
617     /**
618      * Used as the result code of the {@link #getPackageStartability} to indicate
619      * the given package is allowed to start.
620      */
621     static final int PACKAGE_STARTABILITY_OK = 0;
622 
623     /**
624      * Used as the result code of the {@link #getPackageStartability} to indicate
625      * the given package is <b>not</b> allowed to start because it's not found
626      * (could be due to that package is invisible to the given user).
627      */
628     static final int PACKAGE_STARTABILITY_NOT_FOUND = 1;
629 
630     /**
631      * Used as the result code of the {@link #getPackageStartability} to indicate
632      * the given package is <b>not</b> allowed to start because it's not a system app
633      * and the system is running in safe mode.
634      */
635     static final int PACKAGE_STARTABILITY_NOT_SYSTEM = 2;
636 
637     /**
638      * Used as the result code of the {@link #getPackageStartability} to indicate
639      * the given package is <b>not</b> allowed to start because it's currently frozen.
640      */
641     static final int PACKAGE_STARTABILITY_FROZEN = 3;
642 
643     /**
644      * Used as the result code of the {@link #getPackageStartability} to indicate
645      * the given package is <b>not</b> allowed to start because it doesn't support
646      * direct boot.
647      */
648     static final int PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED = 4;
649 
650     private static final String STATIC_SHARED_LIB_DELIMITER = "_";
651     /** Extension of the compressed packages */
652     public final static String COMPRESSED_EXTENSION = ".gz";
653     /** Suffix of stub packages on the system partition */
654     public final static String STUB_SUFFIX = "-Stub";
655 
656     private static final int[] EMPTY_INT_ARRAY = new int[0];
657 
658     /**
659      * Timeout (in milliseconds) after which the watchdog should declare that
660      * our handler thread is wedged.  The usual default for such things is one
661      * minute but we sometimes do very lengthy I/O operations on this thread,
662      * such as installing multi-gigabyte applications, so ours needs to be longer.
663      */
664     static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
665 
666     /**
667      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
668      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
669      * settings entry if available, otherwise we use the hardcoded default.  If it's been
670      * more than this long since the last fstrim, we force one during the boot sequence.
671      *
672      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
673      * one gets run at the next available charging+idle time.  This final mandatory
674      * no-fstrim check kicks in only of the other scheduling criteria is never met.
675      */
676     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
677 
678     /**
679      * Whether verification is enabled by default.
680      */
681     private static final boolean DEFAULT_VERIFY_ENABLE = true;
682 
683     /**
684      * Whether integrity verification is enabled by default.
685      */
686     private static final boolean DEFAULT_INTEGRITY_VERIFY_ENABLE = true;
687 
688     /**
689      * The default maximum time to wait for the verification agent to return in
690      * milliseconds.
691      */
692     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
693 
694     /**
695      * The default maximum time to wait for the integrity verification to return in
696      * milliseconds.
697      */
698     private static final long DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT = 30 * 1000;
699 
700     /**
701      * Timeout duration in milliseconds for enabling package rollback. If we fail to enable
702      * rollback within that period, the install will proceed without rollback enabled.
703      *
704      * <p>If flag value is negative, the default value will be assigned.
705      *
706      * Flag type: {@code long}
707      * Namespace: NAMESPACE_ROLLBACK
708      */
709     private static final String PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS = "enable_rollback_timeout";
710 
711     /**
712      * The default duration to wait for rollback to be enabled in
713      * milliseconds.
714      */
715     private static final long DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS = 10 * 1000;
716 
717     /**
718      * Default IncFs timeouts. Maximum values in IncFs is 1hr.
719      *
720      * <p>If flag value is empty, the default value will be assigned.
721      *
722      * Flag type: {@code String}
723      * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
724      */
725     private static final String PROPERTY_INCFS_DEFAULT_TIMEOUTS = "incfs_default_timeouts";
726 
727     /**
728      * Known digesters with optional timeouts.
729      *
730      * Flag type: {@code String}
731      * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
732      */
733     private static final String PROPERTY_KNOWN_DIGESTERS_LIST = "known_digesters_list";
734 
735     /**
736      * The default response for package verification timeout.
737      *
738      * This can be either PackageManager.VERIFICATION_ALLOW or
739      * PackageManager.VERIFICATION_REJECT.
740      */
741     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
742 
743     /**
744      * Adding an installer package name to a package that does not have one set requires the
745      * INSTALL_PACKAGES permission.
746      *
747      * If the caller targets R, this will throw a SecurityException. Otherwise the request will
748      * fail silently. In both cases, and regardless of whether this change is enabled, the
749      * installer package will remain unchanged.
750      */
751     @ChangeId
752     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
753     private static final long THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE =
754             150857253;
755 
756     /**
757      * Apps targeting Android S and above need to declare dependencies to the public native
758      * shared libraries that are defined by the device maker using {@code uses-native-library} tag
759      * in its {@code AndroidManifest.xml}.
760      *
761      * If any of the dependencies cannot be satisfied, i.e. one of the dependency doesn't exist,
762      * the package manager rejects to install the app. The dependency can be specified as optional
763      * using {@code android:required} attribute in the tag, in which case failing to satisfy the
764      * dependency doesn't stop the installation.
765      * <p>Once installed, an app is provided with only the native shared libraries that are
766      * specified in the app manifest. {@code dlopen}ing a native shared library that doesn't appear
767      * in the app manifest will fail even if it actually exists on the device.
768      */
769     @ChangeId
770     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
771     private static final long ENFORCE_NATIVE_SHARED_LIBRARY_DEPENDENCIES = 142191088;
772 
773     public static final String PLATFORM_PACKAGE_NAME = "android";
774 
775     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
776 
777     private static final String PACKAGE_SCHEME = "package";
778 
779     private static final String COMPANION_PACKAGE_NAME = "com.android.companiondevicemanager";
780 
781     // Compilation reasons.
782     public static final int REASON_FIRST_BOOT = 0;
783     public static final int REASON_BOOT_AFTER_OTA = 1;
784     public static final int REASON_POST_BOOT = 2;
785     public static final int REASON_INSTALL = 3;
786     public static final int REASON_INSTALL_FAST = 4;
787     public static final int REASON_INSTALL_BULK = 5;
788     public static final int REASON_INSTALL_BULK_SECONDARY = 6;
789     public static final int REASON_INSTALL_BULK_DOWNGRADED = 7;
790     public static final int REASON_INSTALL_BULK_SECONDARY_DOWNGRADED = 8;
791     public static final int REASON_BACKGROUND_DEXOPT = 9;
792     public static final int REASON_AB_OTA = 10;
793     public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 11;
794     public static final int REASON_CMDLINE = 12;
795     public static final int REASON_SHARED = 13;
796 
797     public static final int REASON_LAST = REASON_SHARED;
798 
799     /**
800      * The initial enabled state of the cache before other checks are done.
801      */
802     private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
803 
804     /**
805      * Whether to skip all other checks and force the cache to be enabled.
806      *
807      * Setting this to true will cause the cache to be named "debug" to avoid eviction from
808      * build fingerprint changes.
809      */
810     private static final boolean FORCE_PACKAGE_PARSED_CACHE_ENABLED = false;
811 
812     /**
813      * Permissions required in order to receive instant application lifecycle broadcasts.
814      */
815     private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
816             new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
817 
818     private static final String RANDOM_DIR_PREFIX = "~~";
819 
820     final Handler mHandler;
821 
822     private final ProcessLoggingHandler mProcessLoggingHandler;
823 
824     private final boolean mEnableFreeCacheV2;
825 
826     final int mSdkVersion;
827     final Context mContext;
828     final boolean mFactoryTest;
829     final boolean mOnlyCore;
830     final DisplayMetrics mMetrics;
831     final int mDefParseFlags;
832     final String[] mSeparateProcesses;
833     final boolean mIsUpgrade;
834     final boolean mIsPreNUpgrade;
835     final boolean mIsPreNMR1Upgrade;
836     final boolean mIsPreQUpgrade;
837 
838     @GuardedBy("mLock")
839     private boolean mDexOptDialogShown;
840 
841     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
842     // LOCK HELD.  Can be called with mInstallLock held.
843     @GuardedBy("mInstallLock")
844     final Installer mInstaller;
845 
846     /** Directory where installed applications are stored */
847     private final File mAppInstallDir;
848     /** Directory where installed application's 32-bit native libraries are copied. */
849     @VisibleForTesting
850     final File mAppLib32InstallDir;
851 
getAppLib32InstallDir()852     private static File getAppLib32InstallDir() {
853         return new File(Environment.getDataDirectory(), "app-lib");
854     }
855 
856     // ----------------------------------------------------------------
857 
858     // Lock for state used when installing and doing other long running
859     // operations.  Methods that must be called with this lock held have
860     // the suffix "LI".
861     final Object mInstallLock;
862 
863     // ----------------------------------------------------------------
864 
865     // Lock for global state used when modifying package state or settings.
866     // Methods that must be called with this lock held have
867     // the suffix "Locked". Some methods may use the legacy suffix "LP"
868     final PackageManagerTracedLock mLock;
869 
870     // Keys are String (package name), values are Package.
871     @Watched
872     @GuardedBy("mLock")
873     final WatchedArrayMap<String, AndroidPackage> mPackages = new WatchedArrayMap<>();
874     private final SnapshotCache<WatchedArrayMap<String, AndroidPackage>> mPackagesSnapshot =
875             new SnapshotCache.Auto(mPackages, mPackages, "PackageManagerService.mPackages");
876 
877     // Keys are isolated uids and values are the uid of the application
878     // that created the isolated process.
879     @Watched
880     @GuardedBy("mLock")
881     final WatchedSparseIntArray mIsolatedOwners = new WatchedSparseIntArray();
882     private final SnapshotCache<WatchedSparseIntArray> mIsolatedOwnersSnapshot =
883             new SnapshotCache.Auto(mIsolatedOwners, mIsolatedOwners,
884                                    "PackageManagerService.mIsolatedOwners");
885 
886     /**
887      * Tracks new system packages [received in an OTA] that we expect to
888      * find updated user-installed versions. Keys are package name, values
889      * are package location.
890      */
891     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
892 
893     /**
894      * Tracks existing packages prior to receiving an OTA. Keys are package name.
895      * Only non-null during an OTA, and even then it is nulled again once systemReady().
896      */
897     private @Nullable ArraySet<String> mExistingPackages = null;
898 
899     /**
900      * List of code paths that need to be released when the system becomes ready.
901      * <p>
902      * NOTE: We have to delay releasing cblocks for no other reason than we cannot
903      * retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}. When
904      * we no longer need to read that setting, cblock release can occur in the
905      * constructor.
906      *
907      * @see Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL
908      * @see #systemReady()
909      */
910     private @Nullable List<File> mReleaseOnSystemReady;
911 
912     /**
913      * Whether or not system app permissions should be promoted from install to runtime.
914      */
915     boolean mPromoteSystemApps;
916 
917     private final PackageManagerInternal mPmInternal;
918     private final TestUtilityService mTestUtilityService;
919 
920 
921     @Watched
922     @GuardedBy("mLock")
923     final Settings mSettings;
924 
925     /**
926      * Set of package names that are currently "frozen", which means active
927      * surgery is being done on the code/data for that package. The platform
928      * will refuse to launch frozen packages to avoid race conditions.
929      *
930      * @see PackageFreezer
931      */
932     @GuardedBy("mLock")
933     final ArraySet<String> mFrozenPackages = new ArraySet<>();
934 
935     final ProtectedPackages mProtectedPackages;
936 
937     @GuardedBy("mLoadedVolumes")
938     final ArraySet<String> mLoadedVolumes = new ArraySet<>();
939 
940     boolean mFirstBoot;
941 
942     private final boolean mIsEngBuild;
943     private final boolean mIsUserDebugBuild;
944     private final String mIncrementalVersion;
945 
946 
947     PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
948 
949     @GuardedBy("mAvailableFeatures")
950     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
951 
952     @Watched
953     private final InstantAppRegistry mInstantAppRegistry;
954 
955     @GuardedBy("mLock")
956     int mChangedPackagesSequenceNumber;
957     /**
958      * List of changed [installed, removed or updated] packages.
959      * mapping from user id -> sequence number -> package name
960      */
961     @GuardedBy("mLock")
962     final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
963     /**
964      * The sequence number of the last change to a package.
965      * mapping from user id -> package name -> sequence number
966      */
967     @GuardedBy("mLock")
968     final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
969 
970     @GuardedBy("mLock")
971     final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
972 
973     @GuardedBy("mLock")
974     private final SparseIntArray mDefaultPermissionsGrantedUsers = new SparseIntArray();
975 
976     private final ModuleInfoProvider mModuleInfoProvider;
977 
978     private final ApexManager mApexManager;
979 
980     private final Injector mInjector;
981 
982     private final SystemWrapper mSystemWrapper;
983 
984     /**
985      * The list of all system partitions that may contain packages in ascending order of
986      * specificity (the more generic, the earlier in the list a partition appears).
987      */
988     @VisibleForTesting(visibility = Visibility.PRIVATE)
989     public static final List<ScanPartition> SYSTEM_PARTITIONS = Collections.unmodifiableList(
990             PackagePartitions.getOrderedPartitions(ScanPartition::new));
991 
992     private final List<ScanPartition> mDirsToScanAsSystem;
993 
994     private final OverlayConfig mOverlayConfig;
995 
996     @GuardedBy("itself")
997     final private ArrayList<IPackageChangeObserver> mPackageChangeObservers =
998         new ArrayList<>();
999 
1000     // Cached parsed flag value. Invalidated on each flag change.
1001     private PerUidReadTimeouts[] mPerUidReadTimeoutsCache;
1002 
1003     private static final PerUidReadTimeouts[] EMPTY_PER_UID_READ_TIMEOUTS_ARRAY = {};
1004 
1005     /**
1006      * Unit tests will instantiate, extend and/or mock to mock dependencies / behaviors.
1007      *
1008      * NOTE: All getters should return the same instance for every call.
1009      */
1010     @VisibleForTesting(visibility = Visibility.PRIVATE)
1011     public static class Injector {
1012 
1013         @VisibleForTesting(visibility = Visibility.PRIVATE)
1014         interface Producer<T> {
1015             /** Produce an instance of type {@link T} */
produce(Injector injector, PackageManagerService packageManager)1016             T produce(Injector injector, PackageManagerService packageManager);
1017         }
1018 
1019         interface ProducerWithArgument<T, R> {
produce(Injector injector, PackageManagerService packageManager, R argument)1020             T produce(Injector injector, PackageManagerService packageManager, R argument);
1021         }
1022 
1023         interface ServiceProducer {
produce(Class<T> c)1024             <T> T produce(Class<T> c);
1025         }
1026 
1027         @VisibleForTesting(visibility = Visibility.PRIVATE)
1028         static class Singleton<T> {
1029             private final Producer<T> mProducer;
1030             private volatile T mInstance = null;
Singleton(Producer<T> producer)1031             Singleton(Producer<T> producer) {
1032                 this.mProducer = producer;
1033             }
get(Injector injector, PackageManagerService packageManagerService)1034             T get(Injector injector, PackageManagerService packageManagerService) {
1035                 if (mInstance == null) {
1036                     mInstance = mProducer.produce(injector, packageManagerService);
1037                 }
1038                 return mInstance;
1039             }
1040         }
1041 
1042         private PackageManagerService mPackageManager;
1043 
1044         private final PackageAbiHelper mAbiHelper;
1045         private final Context mContext;
1046         private final PackageManagerTracedLock mLock;
1047         private final Installer mInstaller;
1048         private final Object mInstallLock;
1049         private final Handler mBackgroundHandler;
1050         private final Executor mBackgroundExecutor;
1051         private final List<ScanPartition> mSystemPartitions;
1052 
1053 
1054         // ----- producers -----
1055         private final Singleton<ComponentResolver> mComponentResolverProducer;
1056         private final Singleton<PermissionManagerServiceInternal> mPermissionManagerServiceProducer;
1057         private final Singleton<UserManagerService> mUserManagerProducer;
1058         private final Singleton<Settings> mSettingsProducer;
1059         private final Singleton<AppsFilter> mAppsFilterProducer;
1060         private final Singleton<PlatformCompat> mPlatformCompatProducer;
1061         private final Singleton<SystemConfig> mSystemConfigProducer;
1062         private final Singleton<PackageDexOptimizer> mPackageDexOptimizerProducer;
1063         private final Singleton<DexManager> mDexManagerProducer;
1064         private final Singleton<ArtManagerService> mArtManagerServiceProducer;
1065         private final Singleton<ApexManager> mApexManagerProducer;
1066         private final Singleton<ViewCompiler> mViewCompilerProducer;
1067         private final Singleton<IncrementalManager> mIncrementalManagerProducer;
1068         private final Singleton<DefaultAppProvider> mDefaultAppProviderProducer;
1069         private final Singleton<DisplayMetrics> mDisplayMetricsProducer;
1070         private final Producer<PackageParser2> mScanningCachingPackageParserProducer;
1071         private final Producer<PackageParser2> mScanningPackageParserProducer;
1072         private final Producer<PackageParser2> mPreparingPackageParserProducer;
1073         private final Singleton<PackageInstallerService> mPackageInstallerServiceProducer;
1074         private final ProducerWithArgument<InstantAppResolverConnection, ComponentName>
1075                 mInstantAppResolverConnectionProducer;
1076         private final Singleton<LegacyPermissionManagerInternal>
1077                 mLegacyPermissionManagerInternalProducer;
1078         private final SystemWrapper mSystemWrapper;
1079         private final ServiceProducer mGetLocalServiceProducer;
1080         private final ServiceProducer mGetSystemServiceProducer;
1081         private final Singleton<ModuleInfoProvider> mModuleInfoProviderProducer;
1082         private final Singleton<DomainVerificationManagerInternal>
1083                 mDomainVerificationManagerInternalProducer;
1084         private final Singleton<Handler> mHandlerProducer;
1085 
Injector(Context context, PackageManagerTracedLock lock, Installer installer, Object installLock, PackageAbiHelper abiHelper, Handler backgroundHandler, List<ScanPartition> systemPartitions, Producer<ComponentResolver> componentResolverProducer, Producer<PermissionManagerServiceInternal> permissionManagerServiceProducer, Producer<UserManagerService> userManagerProducer, Producer<Settings> settingsProducer, Producer<AppsFilter> appsFilterProducer, Producer<PlatformCompat> platformCompatProducer, Producer<SystemConfig> systemConfigProducer, Producer<PackageDexOptimizer> packageDexOptimizerProducer, Producer<DexManager> dexManagerProducer, Producer<ArtManagerService> artManagerServiceProducer, Producer<ApexManager> apexManagerProducer, Producer<ViewCompiler> viewCompilerProducer, Producer<IncrementalManager> incrementalManagerProducer, Producer<DefaultAppProvider> defaultAppProviderProducer, Producer<DisplayMetrics> displayMetricsProducer, Producer<PackageParser2> scanningCachingPackageParserProducer, Producer<PackageParser2> scanningPackageParserProducer, Producer<PackageParser2> preparingPackageParserProducer, Producer<PackageInstallerService> packageInstallerServiceProducer, ProducerWithArgument<InstantAppResolverConnection, ComponentName> instantAppResolverConnectionProducer, Producer<ModuleInfoProvider> moduleInfoProviderProducer, Producer<LegacyPermissionManagerInternal> legacyPermissionManagerInternalProducer, Producer<DomainVerificationManagerInternal> domainVerificationManagerInternalProducer, Producer<Handler> handlerProducer, SystemWrapper systemWrapper, ServiceProducer getLocalServiceProducer, ServiceProducer getSystemServiceProducer)1086         Injector(Context context, PackageManagerTracedLock lock, Installer installer,
1087                 Object installLock, PackageAbiHelper abiHelper,
1088                 Handler backgroundHandler,
1089                 List<ScanPartition> systemPartitions,
1090                 Producer<ComponentResolver> componentResolverProducer,
1091                 Producer<PermissionManagerServiceInternal> permissionManagerServiceProducer,
1092                 Producer<UserManagerService> userManagerProducer,
1093                 Producer<Settings> settingsProducer,
1094                 Producer<AppsFilter> appsFilterProducer,
1095                 Producer<PlatformCompat> platformCompatProducer,
1096                 Producer<SystemConfig> systemConfigProducer,
1097                 Producer<PackageDexOptimizer> packageDexOptimizerProducer,
1098                 Producer<DexManager> dexManagerProducer,
1099                 Producer<ArtManagerService> artManagerServiceProducer,
1100                 Producer<ApexManager> apexManagerProducer,
1101                 Producer<ViewCompiler> viewCompilerProducer,
1102                 Producer<IncrementalManager> incrementalManagerProducer,
1103                 Producer<DefaultAppProvider> defaultAppProviderProducer,
1104                 Producer<DisplayMetrics> displayMetricsProducer,
1105                 Producer<PackageParser2> scanningCachingPackageParserProducer,
1106                 Producer<PackageParser2> scanningPackageParserProducer,
1107                 Producer<PackageParser2> preparingPackageParserProducer,
1108                 Producer<PackageInstallerService> packageInstallerServiceProducer,
1109                 ProducerWithArgument<InstantAppResolverConnection, ComponentName>
1110                         instantAppResolverConnectionProducer,
1111                 Producer<ModuleInfoProvider> moduleInfoProviderProducer,
1112                 Producer<LegacyPermissionManagerInternal> legacyPermissionManagerInternalProducer,
1113                 Producer<DomainVerificationManagerInternal>
1114                         domainVerificationManagerInternalProducer,
1115                 Producer<Handler> handlerProducer,
1116                 SystemWrapper systemWrapper,
1117                 ServiceProducer getLocalServiceProducer,
1118                 ServiceProducer getSystemServiceProducer) {
1119             mContext = context;
1120             mLock = lock;
1121             mInstaller = installer;
1122             mAbiHelper = abiHelper;
1123             mInstallLock = installLock;
1124             mBackgroundHandler = backgroundHandler;
1125             mBackgroundExecutor = new HandlerExecutor(backgroundHandler);
1126             mSystemPartitions = systemPartitions;
1127             mComponentResolverProducer = new Singleton<>(componentResolverProducer);
1128             mPermissionManagerServiceProducer = new Singleton<>(permissionManagerServiceProducer);
1129             mUserManagerProducer = new Singleton<>(userManagerProducer);
1130             mSettingsProducer = new Singleton<>(settingsProducer);
1131             mAppsFilterProducer = new Singleton<>(appsFilterProducer);
1132             mPlatformCompatProducer = new Singleton<>(platformCompatProducer);
1133             mSystemConfigProducer = new Singleton<>(systemConfigProducer);
1134             mPackageDexOptimizerProducer = new Singleton<>(packageDexOptimizerProducer);
1135             mDexManagerProducer = new Singleton<>(dexManagerProducer);
1136             mArtManagerServiceProducer = new Singleton<>(artManagerServiceProducer);
1137             mApexManagerProducer = new Singleton<>(apexManagerProducer);
1138             mViewCompilerProducer = new Singleton<>(viewCompilerProducer);
1139             mIncrementalManagerProducer = new Singleton<>(incrementalManagerProducer);
1140             mDefaultAppProviderProducer = new Singleton<>(defaultAppProviderProducer);
1141             mDisplayMetricsProducer = new Singleton<>(displayMetricsProducer);
1142             mScanningCachingPackageParserProducer = scanningCachingPackageParserProducer;
1143             mScanningPackageParserProducer = scanningPackageParserProducer;
1144             mPreparingPackageParserProducer = preparingPackageParserProducer;
1145             mPackageInstallerServiceProducer = new Singleton<>(packageInstallerServiceProducer);
1146             mInstantAppResolverConnectionProducer = instantAppResolverConnectionProducer;
1147             mModuleInfoProviderProducer = new Singleton<>(moduleInfoProviderProducer);
1148             mLegacyPermissionManagerInternalProducer = new Singleton<>(
1149                     legacyPermissionManagerInternalProducer);
1150             mSystemWrapper = systemWrapper;
1151             mGetLocalServiceProducer = getLocalServiceProducer;
1152             mGetSystemServiceProducer = getSystemServiceProducer;
1153             mDomainVerificationManagerInternalProducer =
1154                     new Singleton<>(domainVerificationManagerInternalProducer);
1155             mHandlerProducer = new Singleton<>(handlerProducer);
1156         }
1157 
1158         /**
1159          * Bootstraps this injector with the {@link PackageManagerService instance to which it
1160          * belongs.
1161          */
bootstrap(PackageManagerService pm)1162         public void bootstrap(PackageManagerService pm) {
1163             this.mPackageManager = pm;
1164         }
1165 
getUserManagerInternal()1166         public UserManagerInternal getUserManagerInternal() {
1167             return getUserManagerService().getInternalForInjectorOnly();
1168         }
1169 
getAbiHelper()1170         public PackageAbiHelper getAbiHelper() {
1171             return mAbiHelper;
1172         }
1173 
getInstallLock()1174         public Object getInstallLock() {
1175             return mInstallLock;
1176         }
1177 
getSystemPartitions()1178         public List<ScanPartition> getSystemPartitions() {
1179             return mSystemPartitions;
1180         }
1181 
getUserManagerService()1182         public UserManagerService getUserManagerService() {
1183             return mUserManagerProducer.get(this, mPackageManager);
1184         }
1185 
getLock()1186         public PackageManagerTracedLock getLock() {
1187             return mLock;
1188         }
1189 
getInstaller()1190         public Installer getInstaller() {
1191             return mInstaller;
1192         }
1193 
getComponentResolver()1194         public ComponentResolver getComponentResolver() {
1195             return mComponentResolverProducer.get(this, mPackageManager);
1196         }
1197 
getPermissionManagerServiceInternal()1198         public PermissionManagerServiceInternal getPermissionManagerServiceInternal() {
1199             return mPermissionManagerServiceProducer.get(this, mPackageManager);
1200         }
1201 
getContext()1202         public Context getContext() {
1203             return mContext;
1204         }
1205 
getSettings()1206         public Settings getSettings() {
1207             return mSettingsProducer.get(this, mPackageManager);
1208         }
1209 
getAppsFilter()1210         public AppsFilter getAppsFilter() {
1211             return mAppsFilterProducer.get(this, mPackageManager);
1212         }
1213 
getCompatibility()1214         public PlatformCompat getCompatibility() {
1215             return mPlatformCompatProducer.get(this, mPackageManager);
1216         }
1217 
getSystemConfig()1218         public SystemConfig getSystemConfig() {
1219             return mSystemConfigProducer.get(this, mPackageManager);
1220         }
1221 
getPackageDexOptimizer()1222         public PackageDexOptimizer getPackageDexOptimizer() {
1223             return mPackageDexOptimizerProducer.get(this, mPackageManager);
1224         }
1225 
getDexManager()1226         public DexManager getDexManager() {
1227             return mDexManagerProducer.get(this, mPackageManager);
1228         }
1229 
getArtManagerService()1230         public ArtManagerService getArtManagerService() {
1231             return mArtManagerServiceProducer.get(this, mPackageManager);
1232         }
1233 
getApexManager()1234         public ApexManager getApexManager() {
1235             return mApexManagerProducer.get(this, mPackageManager);
1236         }
1237 
getViewCompiler()1238         public ViewCompiler getViewCompiler() {
1239             return mViewCompilerProducer.get(this, mPackageManager);
1240         }
1241 
getBackgroundHandler()1242         public Handler getBackgroundHandler() {
1243             return mBackgroundHandler;
1244         }
1245 
getBackgroundExecutor()1246         public Executor getBackgroundExecutor() {
1247             return mBackgroundExecutor;
1248         }
1249 
getDisplayMetrics()1250         public DisplayMetrics getDisplayMetrics() {
1251             return mDisplayMetricsProducer.get(this, mPackageManager);
1252         }
1253 
getLocalService(Class<T> c)1254         public <T> T getLocalService(Class<T> c) {
1255             return mGetLocalServiceProducer.produce(c);
1256         }
1257 
getSystemService(Class<T> c)1258         public <T> T getSystemService(Class<T> c) {
1259             return mGetSystemServiceProducer.produce(c);
1260         }
1261 
getSystemWrapper()1262         public SystemWrapper getSystemWrapper() {
1263             return mSystemWrapper;
1264         }
1265 
getIncrementalManager()1266         public IncrementalManager getIncrementalManager() {
1267             return mIncrementalManagerProducer.get(this, mPackageManager);
1268         }
1269 
getDefaultAppProvider()1270         public DefaultAppProvider getDefaultAppProvider() {
1271             return mDefaultAppProviderProducer.get(this, mPackageManager);
1272         }
1273 
getScanningCachingPackageParser()1274         public PackageParser2 getScanningCachingPackageParser() {
1275             return mScanningCachingPackageParserProducer.produce(this, mPackageManager);
1276         }
getScanningPackageParser()1277         public PackageParser2 getScanningPackageParser() {
1278             return mScanningPackageParserProducer.produce(this, mPackageManager);
1279         }
getPreparingPackageParser()1280         public PackageParser2 getPreparingPackageParser() {
1281             return mPreparingPackageParserProducer.produce(this, mPackageManager);
1282         }
1283 
getPackageInstallerService()1284         public PackageInstallerService getPackageInstallerService() {
1285             return mPackageInstallerServiceProducer.get(this, mPackageManager);
1286         }
1287 
getInstantAppResolverConnection( ComponentName instantAppResolverComponent)1288         public InstantAppResolverConnection getInstantAppResolverConnection(
1289                 ComponentName instantAppResolverComponent) {
1290             return mInstantAppResolverConnectionProducer.produce(
1291                     this, mPackageManager, instantAppResolverComponent);
1292         }
1293 
getModuleInfoProvider()1294         public ModuleInfoProvider getModuleInfoProvider() {
1295             return mModuleInfoProviderProducer.get(this, mPackageManager);
1296         }
1297 
getLegacyPermissionManagerInternal()1298         public LegacyPermissionManagerInternal getLegacyPermissionManagerInternal() {
1299             return mLegacyPermissionManagerInternalProducer.get(this, mPackageManager);
1300         }
1301 
getDomainVerificationManagerInternal()1302         public DomainVerificationManagerInternal getDomainVerificationManagerInternal() {
1303             return mDomainVerificationManagerInternalProducer.get(this, mPackageManager);
1304         }
1305 
getHandler()1306         public Handler getHandler() {
1307             return mHandlerProducer.get(this, mPackageManager);
1308         }
1309     }
1310 
1311     /** Provides an abstraction to static access to system state. */
1312     public interface SystemWrapper {
disablePackageCaches()1313         void disablePackageCaches();
enablePackageCaches()1314         void enablePackageCaches();
1315     }
1316 
1317     private static class DefaultSystemWrapper implements SystemWrapper {
1318 
1319         @Override
disablePackageCaches()1320         public void disablePackageCaches() {
1321             // disable all package caches that shouldn't apply within system server
1322             PackageManager.disableApplicationInfoCache();
1323             PackageManager.disablePackageInfoCache();
1324             ApplicationPackageManager.invalidateGetPackagesForUidCache();
1325             ApplicationPackageManager.disableGetPackagesForUidCache();
1326             ApplicationPackageManager.invalidateHasSystemFeatureCache();
1327 
1328             // Avoid invalidation-thrashing by preventing cache invalidations from causing property
1329             // writes if the cache isn't enabled yet.  We re-enable writes later when we're
1330             // done initializing.
1331             sSnapshotCorked.incrementAndGet();
1332             PackageManager.corkPackageInfoCache();
1333         }
1334 
1335         @Override
enablePackageCaches()1336         public void enablePackageCaches() {
1337             // Uncork cache invalidations and allow clients to cache package information.
1338             int corking = sSnapshotCorked.decrementAndGet();
1339             if (TRACE_SNAPSHOTS && corking == 0) {
1340                 Log.i(TAG, "snapshot: corking returns to 0");
1341             }
1342             PackageManager.uncorkPackageInfoCache();
1343         }
1344     }
1345 
1346     @VisibleForTesting(visibility = Visibility.PRIVATE)
1347     public static class TestParams {
1348         public ApexManager apexManager;
1349         public @Nullable String appPredictionServicePackage;
1350         public ArtManagerService artManagerService;
1351         public @Nullable String configuratorPackage;
1352         public int defParseFlags;
1353         public DefaultAppProvider defaultAppProvider;
1354         public DexManager dexManager;
1355         public List<ScanPartition> dirsToScanAsSystem;
1356         public @Nullable String documenterPackage;
1357         public boolean factoryTest;
1358         public ArrayMap<String, FeatureInfo> availableFeatures;
1359         public Handler handler;
1360         public @Nullable String incidentReportApproverPackage;
1361         public IncrementalManager incrementalManager;
1362         public PackageInstallerService installerService;
1363         public InstantAppRegistry instantAppRegistry;
1364         public InstantAppResolverConnection instantAppResolverConnection;
1365         public ComponentName instantAppResolverSettingsComponent;
1366         public boolean isPreNmr1Upgrade;
1367         public boolean isPreNupgrade;
1368         public boolean isPreQupgrade;
1369         public boolean isUpgrade;
1370         public LegacyPermissionManagerInternal legacyPermissionManagerInternal;
1371         public DisplayMetrics Metrics;
1372         public ModuleInfoProvider moduleInfoProvider;
1373         public MoveCallbacks moveCallbacks;
1374         public boolean onlyCore;
1375         public OverlayConfig overlayConfig;
1376         public PackageDexOptimizer packageDexOptimizer;
1377         public PackageParser2.Callback packageParserCallback;
1378         public PendingPackageBroadcasts pendingPackageBroadcasts;
1379         public PackageManagerInternal pmInternal;
1380         public TestUtilityService testUtilityService;
1381         public ProcessLoggingHandler processLoggingHandler;
1382         public ProtectedPackages protectedPackages;
1383         public @NonNull String requiredInstallerPackage;
1384         public @NonNull String requiredPermissionControllerPackage;
1385         public @NonNull String requiredUninstallerPackage;
1386         public @Nullable String requiredVerifierPackage;
1387         public String[] separateProcesses;
1388         public @NonNull String servicesExtensionPackageName;
1389         public @Nullable String setupWizardPackage;
1390         public @NonNull String sharedSystemSharedLibraryPackageName;
1391         public @Nullable String storageManagerPackage;
1392         public @Nullable String defaultTextClassifierPackage;
1393         public @Nullable String systemTextClassifierPackage;
1394         public @Nullable String overlayConfigSignaturePackage;
1395         public ViewCompiler viewCompiler;
1396         public @Nullable String retailDemoPackage;
1397         public @Nullable String recentsPackage;
1398         public ComponentName resolveComponentName;
1399         public ArrayMap<String, AndroidPackage> packages;
1400         public boolean enableFreeCacheV2;
1401         public int sdkVersion;
1402         public SystemWrapper systemWrapper;
1403         public File appInstallDir;
1404         public File appLib32InstallDir;
1405         public boolean isEngBuild;
1406         public boolean isUserDebugBuild;
1407         public int sdkInt = Build.VERSION.SDK_INT;
1408         public String incrementalVersion = Build.VERSION.INCREMENTAL;
1409     }
1410 
1411     @Watched
1412     private final AppsFilter mAppsFilter;
1413 
1414     final PackageParser2.Callback mPackageParserCallback;
1415 
1416     // Currently known shared libraries.
1417     @Watched
1418     final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
1419             mSharedLibraries = new WatchedArrayMap<>();
1420     private final SnapshotCache<WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>>
1421             mSharedLibrariesSnapshot =
1422             new SnapshotCache.Auto<>(mSharedLibraries, mSharedLibraries,
1423                                      "PackageManagerService.mSharedLibraries");
1424     @Watched
1425     final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
1426             mStaticLibsByDeclaringPackage = new WatchedArrayMap<>();
1427     private final SnapshotCache<WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>>
1428             mStaticLibsByDeclaringPackageSnapshot =
1429             new SnapshotCache.Auto<>(mStaticLibsByDeclaringPackage, mStaticLibsByDeclaringPackage,
1430                                      "PackageManagerService.mStaticLibsByDeclaringPackage");
1431 
1432     // Mapping from instrumentation class names to info about them.
1433     @Watched
1434     final WatchedArrayMap<ComponentName, ParsedInstrumentation> mInstrumentation =
1435             new WatchedArrayMap<>();
1436     private final SnapshotCache<WatchedArrayMap<ComponentName, ParsedInstrumentation>>
1437             mInstrumentationSnapshot =
1438             new SnapshotCache.Auto<>(mInstrumentation, mInstrumentation,
1439                                      "PackageManagerService.mInstrumentation");
1440 
1441 
1442     // Packages whose data we have transfered into another package, thus
1443     // should no longer exist.
1444     final ArraySet<String> mTransferredPackages = new ArraySet<>();
1445 
1446     // Broadcast actions that are only available to the system.
1447     @GuardedBy("mProtectedBroadcasts")
1448     final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
1449 
1450     /** List of packages waiting for verification. */
1451     final SparseArray<PackageVerificationState> mPendingVerification = new SparseArray<>();
1452 
1453     /** List of packages waiting for rollback to be enabled. */
1454     final SparseArray<VerificationParams> mPendingEnableRollback = new SparseArray<>();
1455 
1456     final PackageInstallerService mInstallerService;
1457 
1458     final ArtManagerService mArtManagerService;
1459 
1460     final PackageDexOptimizer mPackageDexOptimizer;
1461     // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
1462     // is used by other apps).
1463     private final DexManager mDexManager;
1464 
1465     private final ViewCompiler mViewCompiler;
1466 
1467     private AtomicInteger mNextMoveId = new AtomicInteger();
1468     private final MoveCallbacks mMoveCallbacks;
1469 
1470     // Cache of users who need badging.
1471     private final SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
1472 
1473     /** Token for keys in mPendingVerification. */
1474     private int mPendingVerificationToken = 0;
1475 
1476     /** Token for keys in mPendingEnableRollback. */
1477     private int mPendingEnableRollbackToken = 0;
1478 
1479     @Watched(manual = true)
1480     volatile boolean mSystemReady;
1481     @Watched(manual = true)
1482     private volatile boolean mSafeMode;
1483     volatile boolean mHasSystemUidErrors;
1484     @Watched
1485     private final WatchedSparseBooleanArray mWebInstantAppsDisabled =
1486             new WatchedSparseBooleanArray();
1487 
1488     @Watched(manual = true)
1489     private ApplicationInfo mAndroidApplication;
1490     @Watched(manual = true)
1491     final ActivityInfo mResolveActivity = new ActivityInfo();
1492     final ResolveInfo mResolveInfo = new ResolveInfo();
1493     @Watched(manual = true)
1494     private ComponentName mResolveComponentName;
1495     AndroidPackage mPlatformPackage;
1496     ComponentName mCustomResolverComponentName;
1497 
1498     boolean mResolverReplaced = false;
1499 
1500     @NonNull
1501     private final DomainVerificationManagerInternal mDomainVerificationManager;
1502 
1503     /** The service connection to the ephemeral resolver */
1504     final InstantAppResolverConnection mInstantAppResolverConnection;
1505     /** Component used to show resolver settings for Instant Apps */
1506     final ComponentName mInstantAppResolverSettingsComponent;
1507 
1508     /** Activity used to install instant applications */
1509     @Watched(manual = true)
1510     private ActivityInfo mInstantAppInstallerActivity;
1511     @Watched(manual = true)
1512     private final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
1513 
1514     private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
1515             mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
1516 
1517     // Internal interface for permission manager
1518     private final PermissionManagerServiceInternal mPermissionManager;
1519 
1520     @Watched
1521     private final ComponentResolver mComponentResolver;
1522 
1523     // List of packages names to keep cached, even if they are uninstalled for all users
1524     private List<String> mKeepUninstalledPackages;
1525 
1526     // Cached reference to IDevicePolicyManager.
1527     private IDevicePolicyManager mDevicePolicyManager = null;
1528 
1529     private File mCacheDir;
1530 
1531     private Future<?> mPrepareAppDataFuture;
1532 
1533     private final IncrementalManager mIncrementalManager;
1534 
1535     private final DefaultAppProvider mDefaultAppProvider;
1536 
1537     private final LegacyPermissionManagerInternal mLegacyPermissionManager;
1538 
1539     private final PackageProperty mPackageProperty = new PackageProperty();
1540 
1541     // Set of pending broadcasts for aggregating enable/disable of components.
1542     @VisibleForTesting(visibility = Visibility.PACKAGE)
1543     public static class PendingPackageBroadcasts {
1544         // for each user id, a map of <package name -> components within that package>
1545         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1546 
PendingPackageBroadcasts()1547         public PendingPackageBroadcasts() {
1548             mUidMap = new SparseArray<>(2);
1549         }
1550 
get(int userId, String packageName)1551         public ArrayList<String> get(int userId, String packageName) {
1552             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1553             return packages.get(packageName);
1554         }
1555 
put(int userId, String packageName, ArrayList<String> components)1556         public void put(int userId, String packageName, ArrayList<String> components) {
1557             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1558             packages.put(packageName, components);
1559         }
1560 
remove(int userId, String packageName)1561         public void remove(int userId, String packageName) {
1562             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1563             if (packages != null) {
1564                 packages.remove(packageName);
1565             }
1566         }
1567 
remove(int userId)1568         public void remove(int userId) {
1569             mUidMap.remove(userId);
1570         }
1571 
userIdCount()1572         public int userIdCount() {
1573             return mUidMap.size();
1574         }
1575 
userIdAt(int n)1576         public int userIdAt(int n) {
1577             return mUidMap.keyAt(n);
1578         }
1579 
packagesForUserId(int userId)1580         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1581             return mUidMap.get(userId);
1582         }
1583 
size()1584         public int size() {
1585             // total number of pending broadcast entries across all userIds
1586             int num = 0;
1587             for (int i = 0; i< mUidMap.size(); i++) {
1588                 num += mUidMap.valueAt(i).size();
1589             }
1590             return num;
1591         }
1592 
clear()1593         public void clear() {
1594             mUidMap.clear();
1595         }
1596 
getOrAllocate(int userId)1597         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1598             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1599             if (map == null) {
1600                 map = new ArrayMap<>();
1601                 mUidMap.put(userId, map);
1602             }
1603             return map;
1604         }
1605     }
1606     final PendingPackageBroadcasts mPendingBroadcasts;
1607 
1608     static final int SEND_PENDING_BROADCAST = 1;
1609     static final int INIT_COPY = 5;
1610     static final int POST_INSTALL = 9;
1611     static final int WRITE_SETTINGS = 13;
1612     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1613     static final int PACKAGE_VERIFIED = 15;
1614     static final int CHECK_PENDING_VERIFICATION = 16;
1615     // public static final int UNUSED = 17;
1616     // public static final int UNUSED = 18;
1617     static final int WRITE_PACKAGE_LIST = 19;
1618     static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1619     static final int ENABLE_ROLLBACK_STATUS = 21;
1620     static final int ENABLE_ROLLBACK_TIMEOUT = 22;
1621     static final int DEFERRED_NO_KILL_POST_DELETE = 23;
1622     static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
1623     static final int INTEGRITY_VERIFICATION_COMPLETE = 25;
1624     static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
1625     static final int DOMAIN_VERIFICATION = 27;
1626     static final int SNAPSHOT_UNCORK = 28;
1627 
1628     static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
1629     static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
1630 
1631     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1632 
1633     private static final long BROADCAST_DELAY_DURING_STARTUP = 10 * 1000L; // 10 seconds (in millis)
1634     private static final long BROADCAST_DELAY = 1 * 1000L; // 1 second (in millis)
1635 
1636     // When the service constructor finished plus a delay (used for broadcast delay computation)
1637     private long mServiceStartWithDelay;
1638 
1639     private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1640             2 * 60 * 60 * 1000L; /* two hours */
1641 
1642     final UserManagerService mUserManager;
1643 
1644     // Stores a list of users whose package restrictions file needs to be updated
1645     private ArraySet<Integer> mDirtyUsers = new ArraySet<>();
1646 
1647     // Recordkeeping of restore-after-install operations that are currently in flight
1648     // between the Package Manager and the Backup Manager
1649     static class PostInstallData {
1650         @Nullable
1651         public final InstallArgs args;
1652         @NonNull
1653         public final PackageInstalledInfo res;
1654         @Nullable
1655         public final Runnable mPostInstallRunnable;
1656 
PostInstallData(@ullable InstallArgs args, @NonNull PackageInstalledInfo res, @Nullable Runnable postInstallRunnable)1657         PostInstallData(@Nullable InstallArgs args, @NonNull PackageInstalledInfo res,
1658                 @Nullable Runnable postInstallRunnable) {
1659             this.args = args;
1660             this.res = res;
1661             mPostInstallRunnable = postInstallRunnable;
1662         }
1663     }
1664 
1665     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<>();
1666     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1667 
1668     // XML tags for backup/restore of various bits of state
1669     private static final String TAG_PREFERRED_BACKUP = "pa";
1670     private static final String TAG_DEFAULT_APPS = "da";
1671     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1672 
1673     private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1674     private static final String TAG_ALL_GRANTS = "rt-grants";
1675     private static final String TAG_GRANT = "grant";
1676     private static final String ATTR_PACKAGE_NAME = "pkg";
1677 
1678     private static final String TAG_PERMISSION = "perm";
1679     private static final String ATTR_PERMISSION_NAME = "name";
1680     private static final String ATTR_IS_GRANTED = "g";
1681     private static final String ATTR_USER_SET = "set";
1682     private static final String ATTR_USER_FIXED = "fixed";
1683     private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1684 
1685     // System/policy permission grants are not backed up
1686     private static final int SYSTEM_RUNTIME_GRANT_MASK =
1687             FLAG_PERMISSION_POLICY_FIXED
1688             | FLAG_PERMISSION_SYSTEM_FIXED
1689             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1690 
1691     // And we back up these user-adjusted states
1692     private static final int USER_RUNTIME_GRANT_MASK =
1693             FLAG_PERMISSION_USER_SET
1694             | FLAG_PERMISSION_USER_FIXED
1695             | FLAG_PERMISSION_REVOKED_COMPAT;
1696 
1697     final @Nullable String mRequiredVerifierPackage;
1698     final @NonNull String mRequiredInstallerPackage;
1699     final @NonNull String mRequiredUninstallerPackage;
1700     final @NonNull String mRequiredPermissionControllerPackage;
1701     final @Nullable String mSetupWizardPackage;
1702     final @Nullable String mStorageManagerPackage;
1703     final @Nullable String mDefaultTextClassifierPackage;
1704     final @Nullable String mSystemTextClassifierPackageName;
1705     final @Nullable String mDocumenterPackage;
1706     final @Nullable String mConfiguratorPackage;
1707     final @Nullable String mAppPredictionServicePackage;
1708     final @Nullable String mIncidentReportApproverPackage;
1709     final @Nullable String mServicesExtensionPackageName;
1710     final @Nullable String mSharedSystemSharedLibraryPackageName;
1711     final @Nullable String mRetailDemoPackage;
1712     final @Nullable String mOverlayConfigSignaturePackage;
1713     final @Nullable String mRecentsPackage;
1714 
1715     @GuardedBy("mLock")
1716     private final PackageUsage mPackageUsage = new PackageUsage();
1717     private final CompilerStats mCompilerStats = new CompilerStats();
1718 
1719     private final DomainVerificationConnection mDomainVerificationConnection =
1720             new DomainVerificationConnection();
1721 
1722     private class DomainVerificationConnection implements DomainVerificationService.Connection,
1723             DomainVerificationProxyV1.Connection, DomainVerificationProxyV2.Connection {
1724 
1725         @Override
scheduleWriteSettings()1726         public void scheduleWriteSettings() {
1727             synchronized (mLock) {
1728                 PackageManagerService.this.scheduleWriteSettingsLocked();
1729             }
1730         }
1731 
1732         @Override
getCallingUid()1733         public int getCallingUid() {
1734             return Binder.getCallingUid();
1735         }
1736 
1737         @UserIdInt
1738         @Override
getCallingUserId()1739         public int getCallingUserId() {
1740             return UserHandle.getCallingUserId();
1741         }
1742 
1743         @Override
schedule(int code, @Nullable Object object)1744         public void schedule(int code, @Nullable Object object) {
1745             Message message = mHandler.obtainMessage(DOMAIN_VERIFICATION);
1746             message.arg1 = code;
1747             message.obj = object;
1748             mHandler.sendMessage(message);
1749         }
1750 
1751         @Override
getPowerSaveTempWhitelistAppDuration()1752         public long getPowerSaveTempWhitelistAppDuration() {
1753             return PackageManagerService.this.getVerificationTimeout();
1754         }
1755 
1756         @Override
getDeviceIdleInternal()1757         public DeviceIdleInternal getDeviceIdleInternal() {
1758             return mInjector.getLocalService(DeviceIdleInternal.class);
1759         }
1760 
1761         @Override
isCallerPackage(int callingUid, @NonNull String packageName)1762         public boolean isCallerPackage(int callingUid, @NonNull String packageName) {
1763             final int callingUserId = UserHandle.getUserId(callingUid);
1764             return callingUid == getPackageUid(packageName, 0, callingUserId);
1765         }
1766 
1767         @Nullable
1768         @Override
getPackage(@onNull String packageName)1769         public AndroidPackage getPackage(@NonNull String packageName) {
1770             return PackageManagerService.this.getPackage(packageName);
1771         }
1772 
1773         @Override
filterAppAccess(String packageName, int callingUid, int userId)1774         public boolean filterAppAccess(String packageName, int callingUid, int userId) {
1775             return mPmInternal.filterAppAccess(packageName, callingUid, userId);
1776         }
1777 
1778         @Override
getAllUserIds()1779         public int[] getAllUserIds() {
1780             return mUserManager.getUserIds();
1781         }
1782 
1783         @Override
doesUserExist(@serIdInt int userId)1784         public boolean doesUserExist(@UserIdInt int userId) {
1785             return mUserManager.exists(userId);
1786         }
1787 
1788         @Override
withPackageSettingsSnapshot( @onNull Consumer<Function<String, PackageSetting>> block)1789         public void withPackageSettingsSnapshot(
1790                 @NonNull Consumer<Function<String, PackageSetting>> block) {
1791             mPmInternal.withPackageSettingsSnapshot(block);
1792         }
1793 
1794         @Override
withPackageSettingsSnapshotReturning( @onNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output> block)1795         public <Output> Output withPackageSettingsSnapshotReturning(
1796                 @NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
1797                         block) {
1798             return mPmInternal.withPackageSettingsSnapshotReturning(block);
1799         }
1800 
1801         @Override
withPackageSettingsSnapshotThrowing( @onNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>, ExceptionType> block)1802         public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
1803                 @NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>,
1804                         ExceptionType> block) throws ExceptionType {
1805             mPmInternal.withPackageSettingsSnapshotThrowing(block);
1806         }
1807 
1808         @Override
1809         public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
withPackageSettingsSnapshotThrowing2( @onNull FunctionalUtils.ThrowingChecked2Consumer< Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)1810                 withPackageSettingsSnapshotThrowing2(
1811                         @NonNull FunctionalUtils.ThrowingChecked2Consumer<
1812                                 Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)
1813                 throws ExceptionOne, ExceptionTwo {
1814             mPmInternal.withPackageSettingsSnapshotThrowing2(block);
1815         }
1816 
1817         @Override
1818         public <Output, ExceptionType extends Exception> Output
withPackageSettingsSnapshotReturningThrowing( @onNull FunctionalUtils.ThrowingCheckedFunction< Function<String, PackageSetting>, Output, ExceptionType> block)1819                 withPackageSettingsSnapshotReturningThrowing(
1820                         @NonNull FunctionalUtils.ThrowingCheckedFunction<
1821                                 Function<String, PackageSetting>, Output, ExceptionType> block)
1822                 throws ExceptionType {
1823             return mPmInternal.withPackageSettingsSnapshotReturningThrowing(block);
1824         }
1825     }
1826 
1827     /**
1828      * Invalidate the package info cache, which includes updating the cached computer.
1829      * @hide
1830      */
invalidatePackageInfoCache()1831     public static void invalidatePackageInfoCache() {
1832         PackageManager.invalidatePackageInfoCache();
1833         onChanged();
1834     }
1835 
1836     private final Watcher mWatcher = new Watcher() {
1837             @Override
1838                        public void onChange(@Nullable Watchable what) {
1839                 PackageManagerService.this.onChange(what);
1840             }
1841         };
1842 
1843     /**
1844      * A Snapshot is a subset of PackageManagerService state.  A snapshot is either live
1845      * or snapped.  Live snapshots directly reference PackageManagerService attributes.
1846      * Snapped snapshots contain deep copies of the attributes.
1847      */
1848     private class Snapshot {
1849         public static final int LIVE = 1;
1850         public static final int SNAPPED = 2;
1851 
1852         public final Settings settings;
1853         public final WatchedSparseIntArray isolatedOwners;
1854         public final WatchedArrayMap<String, AndroidPackage> packages;
1855         public final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibs;
1856         public final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>> staticLibs;
1857         public final WatchedArrayMap<ComponentName, ParsedInstrumentation> instrumentation;
1858         public final WatchedSparseBooleanArray webInstantAppsDisabled;
1859         public final ComponentName resolveComponentName;
1860         public final ActivityInfo resolveActivity;
1861         public final ActivityInfo instantAppInstallerActivity;
1862         public final ResolveInfo instantAppInstallerInfo;
1863         public final InstantAppRegistry instantAppRegistry;
1864         public final ApplicationInfo androidApplication;
1865         public final String appPredictionServicePackage;
1866         public final AppsFilter appsFilter;
1867         public final ComponentResolver componentResolver;
1868         public final PackageManagerService service;
1869 
Snapshot(int type)1870         Snapshot(int type) {
1871             if (type == Snapshot.SNAPPED) {
1872                 settings = mSettings.snapshot();
1873                 isolatedOwners = mIsolatedOwnersSnapshot.snapshot();
1874                 packages = mPackagesSnapshot.snapshot();
1875                 sharedLibs = mSharedLibrariesSnapshot.snapshot();
1876                 staticLibs = mStaticLibsByDeclaringPackageSnapshot.snapshot();
1877                 instrumentation = mInstrumentationSnapshot.snapshot();
1878                 resolveComponentName = mResolveComponentName.clone();
1879                 resolveActivity = new ActivityInfo(mResolveActivity);
1880                 instantAppInstallerActivity =
1881                         (mInstantAppInstallerActivity == null)
1882                         ? null
1883                         : new ActivityInfo(mInstantAppInstallerActivity);
1884                 instantAppInstallerInfo = new ResolveInfo(mInstantAppInstallerInfo);
1885                 webInstantAppsDisabled = mWebInstantAppsDisabled.snapshot();
1886                 instantAppRegistry = mInstantAppRegistry.snapshot();
1887                 androidApplication =
1888                         (mAndroidApplication == null)
1889                         ? null
1890                         : new ApplicationInfo(mAndroidApplication);
1891                 appPredictionServicePackage = mAppPredictionServicePackage;
1892                 appsFilter = mAppsFilter.snapshot();
1893                 componentResolver = mComponentResolver.snapshot();
1894             } else if (type == Snapshot.LIVE) {
1895                 settings = mSettings;
1896                 isolatedOwners = mIsolatedOwners;
1897                 packages = mPackages;
1898                 sharedLibs = mSharedLibraries;
1899                 staticLibs = mStaticLibsByDeclaringPackage;
1900                 instrumentation = mInstrumentation;
1901                 resolveComponentName = mResolveComponentName;
1902                 resolveActivity = mResolveActivity;
1903                 instantAppInstallerActivity = mInstantAppInstallerActivity;
1904                 instantAppInstallerInfo = mInstantAppInstallerInfo;
1905                 webInstantAppsDisabled = mWebInstantAppsDisabled;
1906                 instantAppRegistry = mInstantAppRegistry;
1907                 androidApplication = mAndroidApplication;
1908                 appPredictionServicePackage = mAppPredictionServicePackage;
1909                 appsFilter = mAppsFilter;
1910                 componentResolver = mComponentResolver;
1911             } else {
1912                 throw new IllegalArgumentException();
1913             }
1914             service = PackageManagerService.this;
1915         }
1916     }
1917 
1918     /**
1919      * A {@link Computer} provides a set of functions that can operate on live data or snapshot
1920      * data.  At this time, the {@link Computer} is implemented by the
1921      * {@link ComputerEngine}, which is in turn extended by {@link ComputerLocked}.
1922      *
1923      * New functions must be added carefully.
1924      * <ol>
1925      * <li> New functions must be true functions with respect to data collected in a
1926      * {@link Snapshot}.  Such data may never be modified from inside a {@link Computer}
1927      * function.
1928      * </li>
1929      *
1930      * <li> A new function must be implemented in {@link ComputerEngine}.
1931      * </li>
1932      *
1933      * <li> A new function must be overridden in {@link ComputerLocked} if the function
1934      * cannot safely access live data without holding the PackageManagerService lock.  The
1935      * form of the {@link ComputerLocked} function must be a single call to the
1936      * {@link ComputerEngine} implementation, wrapped in a <code>synchronized</code>
1937      * block.  Functions in {@link ComputerLocked} should never include any other code.
1938      * </li>
1939      *
1940      * Care must be taken when deciding if a function should be overridden in
1941      * {@link ComputerLocked}.  The complex lock relationships of PackageManagerService
1942      * and other managers (like PermissionManager) mean deadlock is possible.  On the
1943      * other hand, not overriding in {@link ComputerLocked} may leave a function walking
1944      * unstable data.
1945      *
1946      * To coax developers to consider such issues carefully, all methods in
1947      * {@link Computer} must be annotated with <code>@LiveImplementation(override =
1948      * MANDATORY)</code> or <code>LiveImplementation(locked = NOT_ALLOWED)</code>.  A unit
1949      * test verifies the annotation and that the annotation corresponds to the code in
1950      * {@link ComputerEngine} and {@link ComputerLocked}.
1951      */
1952     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
1953     protected interface Computer {
1954 
1955         /**
1956          * Every method must be annotated.
1957          */
1958         @Target({ ElementType.METHOD })
1959         @Retention(RetentionPolicy.RUNTIME)
1960         public @interface LiveImplementation {
1961             // A Computer method must be annotated with one of the following values:
1962             //   MANDATORY - the method must be overridden in ComputerEngineLive.  The
1963             //     format of the override is a call to the super method, wrapped in a
1964             //     synchronization block.
1965             //   NOT_ALLOWED - the method may not appear in the live computer.  It must
1966             //     be final in the ComputerEngine.
1967             int MANDATORY = 1;
1968             int NOT_ALLOWED = 2;
override()1969             int override() default MANDATORY;
rationale()1970             String rationale() default "";
1971         }
1972 
1973         /**
1974          * Administrative statistics: record that the snapshot has been used.  Every call
1975          * to use() increments the usage counter.
1976          */
1977         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
use()1978         default void use() {
1979         }
1980 
1981         /**
1982          * Fetch the snapshot usage counter.
1983          * @return The number of times this snapshot was used.
1984          */
1985         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getUsed()1986         default int getUsed() {
1987             return 0;
1988         }
1989 
1990         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits)1991         @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
1992                 int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid,
1993                 int userId, boolean resolveForStart, boolean allowDynamicSplits);
1994         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId)1995         @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
1996                 int flags, int userId);
1997         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps)1998         @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, String resolvedType,
1999                 int flags, int userId, int callingUid, boolean includeInstantApps);
2000         @LiveImplementation(override = LiveImplementation.MANDATORY)
queryIntentActivitiesInternalBody(Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)2001         @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent,
2002                 String resolvedType, int flags, int filterCallingUid, int userId,
2003                 boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
2004                 String instantAppPkgName);
2005         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getActivityInfo(ComponentName component, int flags, int userId)2006         ActivityInfo getActivityInfo(ComponentName component, int flags, int userId);
2007         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getActivityInfoInternal(ComponentName component, int flags, int filterCallingUid, int userId)2008         ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
2009                 int filterCallingUid, int userId);
2010         @LiveImplementation(override = LiveImplementation.MANDATORY)
getPackage(String packageName)2011         AndroidPackage getPackage(String packageName);
2012         @LiveImplementation(override = LiveImplementation.MANDATORY)
getPackage(int uid)2013         AndroidPackage getPackage(int uid);
2014         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int filterCallingUid, int userId)2015         ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2016                 int filterCallingUid, int userId);
2017         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getApplicationInfo(String packageName, int flags, int userId)2018         ApplicationInfo getApplicationInfo(String packageName, int flags, int userId);
2019         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getApplicationInfoInternal(String packageName, int flags, int filterCallingUid, int userId)2020         ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
2021                 int filterCallingUid, int userId);
2022         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getDefaultHomeActivity(int userId)2023         ComponentName getDefaultHomeActivity(int userId);
2024         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)2025         ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId);
2026         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)2027         CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType,
2028                 int flags, int sourceUserId, int parentUserId);
2029         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getHomeIntent()2030         Intent getHomeIntent();
2031         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId)2032         List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
2033                 String resolvedType, int userId);
2034         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
applyPostResolutionFilter(@onNull List<ResolveInfo> resolveInfos, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, boolean resolveForStart, int userId, Intent intent)2035         List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
2036                 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
2037                 boolean resolveForStart, int userId, Intent intent);
2038         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
generatePackageInfo(PackageSetting ps, int flags, int userId)2039         PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId);
2040         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getPackageInfo(String packageName, int flags, int userId)2041         PackageInfo getPackageInfo(String packageName, int flags, int userId);
2042         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getPackageInfoInternal(String packageName, long versionCode, int flags, int filterCallingUid, int userId)2043         PackageInfo getPackageInfoInternal(String packageName, long versionCode, int flags,
2044                 int filterCallingUid, int userId);
2045         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getPackageSetting(String packageName)2046         PackageSetting getPackageSetting(String packageName);
2047         @LiveImplementation(override = LiveImplementation.MANDATORY)
getPackageSettingInternal(String packageName, int callingUid)2048         PackageSetting getPackageSettingInternal(String packageName, int callingUid);
2049         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getInstalledPackages(int flags, int userId)2050         ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId);
2051         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, int sourceUserId, int targetUserId)2052         ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
2053                 int sourceUserId, int targetUserId);
2054         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getServiceInfo(ComponentName component, int flags, int userId)2055         ServiceInfo getServiceInfo(ComponentName component, int flags, int userId);
2056         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getSharedLibraryInfoLPr(String name, long version)2057         SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version);
2058         @LiveImplementation(override = LiveImplementation.MANDATORY)
getInstantAppPackageName(int callingUid)2059         String getInstantAppPackageName(int callingUid);
2060         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
resolveExternalPackageNameLPr(AndroidPackage pkg)2061         String resolveExternalPackageNameLPr(AndroidPackage pkg);
2062         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
resolveInternalPackageNameLPr(String packageName, long versionCode)2063         String resolveInternalPackageNameLPr(String packageName, long versionCode);
2064         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getPackagesForUid(int uid)2065         String[] getPackagesForUid(int uid);
2066         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getProfileParent(int userId)2067         UserInfo getProfileParent(int userId);
2068         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
canViewInstantApps(int callingUid, int userId)2069         boolean canViewInstantApps(int callingUid, int userId);
2070         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
filterSharedLibPackageLPr(@ullable PackageSetting ps, int uid, int userId, int flags)2071         boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
2072                 int flags);
2073         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isCallerSameApp(String packageName, int uid)2074         boolean isCallerSameApp(String packageName, int uid);
2075         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isComponentVisibleToInstantApp(@ullable ComponentName component)2076         boolean isComponentVisibleToInstantApp(@Nullable ComponentName component);
2077         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isComponentVisibleToInstantApp(@ullable ComponentName component, @ComponentType int type)2078         boolean isComponentVisibleToInstantApp(@Nullable ComponentName component,
2079                 @ComponentType int type);
2080         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, String resolvedType, int flags)2081         boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
2082                 String resolvedType, int flags);
2083         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isInstantApp(String packageName, int userId)2084         boolean isInstantApp(String packageName, int userId);
2085         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid)2086         boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid);
2087         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isSameProfileGroup(@serIdInt int callerUserId, @UserIdInt int userId)2088         boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId);
2089         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, @Nullable ComponentName component, @ComponentType int componentType, int userId)2090         boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
2091                 @Nullable ComponentName component, @ComponentType int componentType, int userId);
2092         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, int userId)2093         boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
2094                 int userId);
2095         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
shouldFilterApplicationLocked(@onNull SharedUserSetting sus, int callingUid, int userId)2096         boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
2097                 int userId);
2098         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
checkUidPermission(String permName, int uid)2099         int checkUidPermission(String permName, int uid);
2100         @LiveImplementation(override = LiveImplementation.MANDATORY)
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)2101         int getPackageUidInternal(String packageName, int flags, int userId, int callingUid);
2102         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForApplication(int flags, int userId)2103         int updateFlagsForApplication(int flags, int userId);
2104         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForComponent(int flags, int userId)2105         int updateFlagsForComponent(int flags, int userId);
2106         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForPackage(int flags, int userId)2107         int updateFlagsForPackage(int flags, int userId);
2108         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc)2109         int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
2110                 boolean isImplicitImageCaptureIntentAndNotSetByDpc);
2111         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc)2112         int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
2113                 boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc);
2114         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)2115         void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
2116                 boolean requireFullPermission, boolean checkShell, String message);
2117         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)2118         void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
2119                 boolean requireFullPermission, boolean checkShell, String message);
2120         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)2121         void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
2122                 boolean requireFullPermission, boolean checkShell,
2123                 boolean requirePermissionWhenSameUser, String message);
2124         @LiveImplementation(override = LiveImplementation.MANDATORY)
getSigningDetails(@onNull String packageName)2125         SigningDetails getSigningDetails(@NonNull String packageName);
2126         @LiveImplementation(override = LiveImplementation.MANDATORY)
getSigningDetails(int uid)2127         SigningDetails getSigningDetails(int uid);
2128         @LiveImplementation(override = LiveImplementation.MANDATORY)
filterAppAccess(AndroidPackage pkg, int callingUid, int userId)2129         boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId);
2130         @LiveImplementation(override = LiveImplementation.MANDATORY)
filterAppAccess(String packageName, int callingUid, int userId)2131         boolean filterAppAccess(String packageName, int callingUid, int userId);
2132         @LiveImplementation(override = LiveImplementation.MANDATORY)
dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState)2133         void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState);
2134         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
findPreferredActivityInternal(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered)2135         FindPreferredActivityBodyResult findPreferredActivityInternal(Intent intent,
2136                 String resolvedType, int flags, List<ResolveInfo> query, boolean always,
2137                 boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered);
2138         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)2139         ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags,
2140                 List<ResolveInfo> query, boolean debug, int userId);
2141     }
2142 
2143     /**
2144      * This class contains the implementation of the Computer functions.  It
2145      * is entirely self-contained - it has no implicit access to
2146      * PackageManagerService.
2147      */
2148     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
2149     protected static class ComputerEngine implements Computer {
2150 
2151         // The administrative use counter.
2152         private int mUsed = 0;
2153 
2154         // Cached attributes.  The names in this class are the same as the
2155         // names in PackageManagerService; see that class for documentation.
2156         protected final Settings mSettings;
2157         private final WatchedSparseIntArray mIsolatedOwners;
2158         private final WatchedArrayMap<String, AndroidPackage> mPackages;
2159         private final WatchedArrayMap<ComponentName, ParsedInstrumentation>
2160                 mInstrumentation;
2161         private final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
2162                 mStaticLibsByDeclaringPackage;
2163         private final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
2164                 mSharedLibraries;
2165         private final ComponentName mLocalResolveComponentName;
2166         private final ActivityInfo mResolveActivity;
2167         private final WatchedSparseBooleanArray mWebInstantAppsDisabled;
2168         private final ActivityInfo mLocalInstantAppInstallerActivity;
2169         private final ResolveInfo mInstantAppInstallerInfo;
2170         private final InstantAppRegistry mInstantAppRegistry;
2171         private final ApplicationInfo mLocalAndroidApplication;
2172         private final AppsFilter mAppsFilter;
2173 
2174         // Immutable service attribute
2175         private final String mAppPredictionServicePackage;
2176 
2177         // The following are not cloned since changes to these have never
2178         // been guarded by the PMS lock.
2179         private final Context mContext;
2180         private final UserManagerService mUserManager;
2181         private final PermissionManagerServiceInternal mPermissionManager;
2182         private final ApexManager mApexManager;
2183         private final Injector mInjector;
2184         private final ComponentResolver mComponentResolver;
2185         private final InstantAppResolverConnection mInstantAppResolverConnection;
2186         private final DefaultAppProvider mDefaultAppProvider;
2187         private final DomainVerificationManagerInternal mDomainVerificationManager;
2188         private final PackageDexOptimizer mPackageDexOptimizer;
2189         private final DexManager mDexManager;
2190         private final CompilerStats mCompilerStats;
2191 
2192         // PackageManagerService attributes that are primitives are referenced through the
2193         // pms object directly.  Primitives are the only attributes so referenced.
2194         protected final PackageManagerService mService;
safeMode()2195         private boolean safeMode() {
2196             return mService.mSafeMode;
2197         }
resolveComponentName()2198         protected ComponentName resolveComponentName() {
2199             return mLocalResolveComponentName;
2200         }
instantAppInstallerActivity()2201         protected ActivityInfo instantAppInstallerActivity() {
2202             return mLocalInstantAppInstallerActivity;
2203         }
androidApplication()2204         protected ApplicationInfo androidApplication() {
2205             return mLocalAndroidApplication;
2206         }
2207 
ComputerEngine(Snapshot args)2208         ComputerEngine(Snapshot args) {
2209             mSettings = args.settings;
2210             mIsolatedOwners = args.isolatedOwners;
2211             mPackages = args.packages;
2212             mSharedLibraries = args.sharedLibs;
2213             mStaticLibsByDeclaringPackage = args.staticLibs;
2214             mInstrumentation = args.instrumentation;
2215             mWebInstantAppsDisabled = args.webInstantAppsDisabled;
2216             mLocalResolveComponentName = args.resolveComponentName;
2217             mResolveActivity = args.resolveActivity;
2218             mLocalInstantAppInstallerActivity = args.instantAppInstallerActivity;
2219             mInstantAppInstallerInfo = args.instantAppInstallerInfo;
2220             mInstantAppRegistry = args.instantAppRegistry;
2221             mLocalAndroidApplication = args.androidApplication;
2222             mAppsFilter = args.appsFilter;
2223             mComponentResolver = args.componentResolver;
2224 
2225             mAppPredictionServicePackage = args.appPredictionServicePackage;
2226 
2227             // The following are not cached copies.  Instead they are
2228             // references to outside services.
2229             mPermissionManager = args.service.mPermissionManager;
2230             mUserManager = args.service.mUserManager;
2231             mContext = args.service.mContext;
2232             mInjector = args.service.mInjector;
2233             mApexManager = args.service.mApexManager;
2234             mInstantAppResolverConnection = args.service.mInstantAppResolverConnection;
2235             mDefaultAppProvider = args.service.mDefaultAppProvider;
2236             mDomainVerificationManager = args.service.mDomainVerificationManager;
2237             mPackageDexOptimizer = args.service.mPackageDexOptimizer;
2238             mDexManager = args.service.mDexManager;
2239             mCompilerStats = args.service.mCompilerStats;
2240 
2241             // Used to reference PMS attributes that are primitives and which are not
2242             // updated under control of the PMS lock.
2243             mService = args.service;
2244         }
2245 
2246         /**
2247          * Record that the snapshot was used.
2248          */
use()2249         public final void use() {
2250             mUsed++;
2251         }
2252 
2253         /**
2254          * Return the usage counter.
2255          */
getUsed()2256         public final int getUsed() {
2257             return mUsed;
2258         }
2259 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits)2260         public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
2261                 String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
2262                 int filterCallingUid, int userId, boolean resolveForStart,
2263                 boolean allowDynamicSplits) {
2264             if (!mUserManager.exists(userId)) return Collections.emptyList();
2265             final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
2266             enforceCrossUserPermission(Binder.getCallingUid(), userId,
2267                     false /* requireFullPermission */, false /* checkShell */,
2268                     "query intent activities");
2269             final String pkgName = intent.getPackage();
2270             ComponentName comp = intent.getComponent();
2271             if (comp == null) {
2272                 if (intent.getSelector() != null) {
2273                     intent = intent.getSelector();
2274                     comp = intent.getComponent();
2275                 }
2276             }
2277 
2278             flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
2279                     comp != null || pkgName != null /*onlyExposedExplicitly*/,
2280                     isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
2281                             flags));
2282             if (comp != null) {
2283                 final List<ResolveInfo> list = new ArrayList<>(1);
2284                 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
2285                 if (ai != null) {
2286                     // When specifying an explicit component, we prevent the activity from being
2287                     // used when either 1) the calling package is normal and the activity is within
2288                     // an ephemeral application or 2) the calling package is ephemeral and the
2289                     // activity is not visible to ephemeral applications.
2290                     final boolean matchInstantApp =
2291                             (flags & PackageManager.MATCH_INSTANT) != 0;
2292                     final boolean matchVisibleToInstantAppOnly =
2293                             (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
2294                     final boolean matchExplicitlyVisibleOnly =
2295                             (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
2296                     final boolean isCallerInstantApp =
2297                             instantAppPkgName != null;
2298                     final boolean isTargetSameInstantApp =
2299                             comp.getPackageName().equals(instantAppPkgName);
2300                     final boolean isTargetInstantApp =
2301                             (ai.applicationInfo.privateFlags
2302                                     & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
2303                     final boolean isTargetVisibleToInstantApp =
2304                             (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
2305                     final boolean isTargetExplicitlyVisibleToInstantApp =
2306                             isTargetVisibleToInstantApp
2307                             && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP)
2308                             == 0;
2309                     final boolean isTargetHiddenFromInstantApp =
2310                             !isTargetVisibleToInstantApp
2311                             || (matchExplicitlyVisibleOnly
2312                                     && !isTargetExplicitlyVisibleToInstantApp);
2313                     final boolean blockInstantResolution =
2314                             !isTargetSameInstantApp
2315                             && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
2316                                     || (matchVisibleToInstantAppOnly && isCallerInstantApp
2317                                             && isTargetHiddenFromInstantApp));
2318                     final boolean blockNormalResolution =
2319                             !resolveForStart && !isTargetInstantApp && !isCallerInstantApp
2320                                     && shouldFilterApplicationLocked(
2321                                     getPackageSettingInternal(ai.applicationInfo.packageName,
2322                                             Process.SYSTEM_UID), filterCallingUid, userId);
2323                     if (!blockInstantResolution && !blockNormalResolution) {
2324                         final ResolveInfo ri = new ResolveInfo();
2325                         ri.activityInfo = ai;
2326                         list.add(ri);
2327                     }
2328                 }
2329 
2330                 List<ResolveInfo> result = applyPostResolutionFilter(
2331                         list, instantAppPkgName, allowDynamicSplits, filterCallingUid,
2332                         resolveForStart,
2333                         userId, intent);
2334                 return result;
2335             }
2336 
2337             QueryIntentActivitiesResult lockedResult =
2338                     queryIntentActivitiesInternalBody(
2339                         intent, resolvedType, flags, filterCallingUid, userId, resolveForStart,
2340                         allowDynamicSplits, pkgName, instantAppPkgName);
2341             if (lockedResult.answer != null) {
2342                 return lockedResult.answer;
2343             }
2344 
2345             if (lockedResult.addInstant) {
2346                 String callingPkgName = getInstantAppPackageName(filterCallingUid);
2347                 boolean isRequesterInstantApp = isInstantApp(callingPkgName, userId);
2348                 lockedResult.result = maybeAddInstantAppInstaller(lockedResult.result, intent,
2349                         resolvedType, flags, userId, resolveForStart, isRequesterInstantApp);
2350             }
2351             if (lockedResult.sortResult) {
2352                 Collections.sort(lockedResult.result, RESOLVE_PRIORITY_SORTER);
2353             }
2354             return applyPostResolutionFilter(
2355                     lockedResult.result, instantAppPkgName, allowDynamicSplits, filterCallingUid,
2356                     resolveForStart, userId, intent);
2357         }
2358 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId)2359         public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
2360                 String resolvedType, int flags, int userId) {
2361             return queryIntentActivitiesInternal(
2362                     intent, resolvedType, flags, 0 /*privateResolveFlags*/, Binder.getCallingUid(),
2363                     userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
2364         }
2365 
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps)2366         public final @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
2367                 String resolvedType, int flags, int userId, int callingUid,
2368                 boolean includeInstantApps) {
2369             if (!mUserManager.exists(userId)) return Collections.emptyList();
2370             enforceCrossUserOrProfilePermission(callingUid,
2371                     userId,
2372                     false /*requireFullPermission*/,
2373                     false /*checkShell*/,
2374                     "query intent receivers");
2375             final String instantAppPkgName = getInstantAppPackageName(callingUid);
2376             flags = updateFlagsForResolve(flags, userId, callingUid, includeInstantApps,
2377                     false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
2378             ComponentName comp = intent.getComponent();
2379             if (comp == null) {
2380                 if (intent.getSelector() != null) {
2381                     intent = intent.getSelector();
2382                     comp = intent.getComponent();
2383                 }
2384             }
2385             if (comp != null) {
2386                 final List<ResolveInfo> list = new ArrayList<>(1);
2387                 final ServiceInfo si = getServiceInfo(comp, flags, userId);
2388                 if (si != null) {
2389                     // When specifying an explicit component, we prevent the service from being
2390                     // used when either 1) the service is in an instant application and the
2391                     // caller is not the same instant application or 2) the calling package is
2392                     // ephemeral and the activity is not visible to ephemeral applications.
2393                     final boolean matchInstantApp =
2394                             (flags & PackageManager.MATCH_INSTANT) != 0;
2395                     final boolean matchVisibleToInstantAppOnly =
2396                             (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
2397                     final boolean isCallerInstantApp =
2398                             instantAppPkgName != null;
2399                     final boolean isTargetSameInstantApp =
2400                             comp.getPackageName().equals(instantAppPkgName);
2401                     final boolean isTargetInstantApp =
2402                             (si.applicationInfo.privateFlags
2403                                     & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
2404                     final boolean isTargetHiddenFromInstantApp =
2405                             (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
2406                     final boolean blockInstantResolution =
2407                             !isTargetSameInstantApp
2408                             && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
2409                                     || (matchVisibleToInstantAppOnly && isCallerInstantApp
2410                                             && isTargetHiddenFromInstantApp));
2411 
2412                     final boolean blockNormalResolution = !isTargetInstantApp && !isCallerInstantApp
2413                             && shouldFilterApplicationLocked(
2414                             getPackageSettingInternal(si.applicationInfo.packageName,
2415                                     Process.SYSTEM_UID), callingUid, userId);
2416                     if (!blockInstantResolution && !blockNormalResolution) {
2417                         final ResolveInfo ri = new ResolveInfo();
2418                         ri.serviceInfo = si;
2419                         list.add(ri);
2420                     }
2421                 }
2422                 return list;
2423             }
2424 
2425             return queryIntentServicesInternalBody(intent, resolvedType, flags,
2426                     userId, callingUid, instantAppPkgName);
2427         }
2428 
queryIntentServicesInternalBody(Intent intent, String resolvedType, int flags, int userId, int callingUid, String instantAppPkgName)2429         protected @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent,
2430                 String resolvedType, int flags, int userId, int callingUid,
2431                 String instantAppPkgName) {
2432             // reader
2433             String pkgName = intent.getPackage();
2434             if (pkgName == null) {
2435                 final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
2436                         resolvedType, flags, userId);
2437                 if (resolveInfos == null) {
2438                     return Collections.emptyList();
2439                 }
2440                 return applyPostServiceResolutionFilter(
2441                         resolveInfos, instantAppPkgName, userId, callingUid);
2442             }
2443             final AndroidPackage pkg = mPackages.get(pkgName);
2444             if (pkg != null) {
2445                 final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
2446                         resolvedType, flags, pkg.getServices(),
2447                         userId);
2448                 if (resolveInfos == null) {
2449                     return Collections.emptyList();
2450                 }
2451                 return applyPostServiceResolutionFilter(
2452                         resolveInfos, instantAppPkgName, userId, callingUid);
2453             }
2454             return Collections.emptyList();
2455         }
2456 
queryIntentActivitiesInternalBody( Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)2457         public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
2458                 Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
2459                 boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
2460                 String instantAppPkgName) {
2461             // reader
2462             boolean sortResult = false;
2463             boolean addInstant = false;
2464             List<ResolveInfo> result = null;
2465             if (pkgName == null) {
2466                 List<CrossProfileIntentFilter> matchingFilters =
2467                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
2468                 // Check for results that need to skip the current profile.
2469                 ResolveInfo skipProfileInfo  = querySkipCurrentProfileIntents(matchingFilters,
2470                         intent, resolvedType, flags, userId);
2471                 if (skipProfileInfo != null) {
2472                     List<ResolveInfo> xpResult = new ArrayList<>(1);
2473                     xpResult.add(skipProfileInfo);
2474                     return new QueryIntentActivitiesResult(
2475                             applyPostResolutionFilter(
2476                                     filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
2477                                     allowDynamicSplits, filterCallingUid, resolveForStart, userId,
2478                                     intent));
2479                 }
2480 
2481                 // Check for results in the current profile.
2482                 result = filterIfNotSystemUser(mComponentResolver.queryActivities(
2483                         intent, resolvedType, flags, userId), userId);
2484                 addInstant = isInstantAppResolutionAllowed(intent, result, userId,
2485                         false /*skipPackageCheck*/, flags);
2486                 // Check for cross profile results.
2487                 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
2488                 CrossProfileDomainInfo specificXpInfo = queryCrossProfileIntents(
2489                         matchingFilters, intent, resolvedType, flags, userId,
2490                         hasNonNegativePriorityResult);
2491                 if (intent.hasWebURI()) {
2492                     CrossProfileDomainInfo generalXpInfo = null;
2493                     final UserInfo parent = getProfileParent(userId);
2494                     if (parent != null) {
2495                         generalXpInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
2496                                 flags, userId, parent.id);
2497                     }
2498 
2499                     // Generalized cross profile intents take precedence over specific.
2500                     // Note that this is the opposite of the intuitive order.
2501                     CrossProfileDomainInfo prioritizedXpInfo =
2502                             generalXpInfo != null ? generalXpInfo : specificXpInfo;
2503 
2504                     if (!addInstant) {
2505                         if (result.isEmpty() && prioritizedXpInfo != null) {
2506                             // No result in current profile, but found candidate in parent user.
2507                             // And we are not going to add ephemeral app, so we can return the
2508                             // result straight away.
2509                             result.add(prioritizedXpInfo.resolveInfo);
2510                             return new QueryIntentActivitiesResult(
2511                                     applyPostResolutionFilter(result, instantAppPkgName,
2512                                             allowDynamicSplits, filterCallingUid, resolveForStart,
2513                                             userId, intent));
2514                         } else if (result.size() <= 1 && prioritizedXpInfo == null) {
2515                             // No result in parent user and <= 1 result in current profile, and we
2516                             // are not going to add ephemeral app, so we can return the result
2517                             // without further processing.
2518                             return new QueryIntentActivitiesResult(
2519                                     applyPostResolutionFilter(result, instantAppPkgName,
2520                                             allowDynamicSplits, filterCallingUid, resolveForStart,
2521                                             userId, intent));
2522                         }
2523                     }
2524 
2525                     // We have more than one candidate (combining results from current and parent
2526                     // profile), so we need filtering and sorting.
2527                     result = filterCandidatesWithDomainPreferredActivitiesLPr(
2528                             intent, flags, result, prioritizedXpInfo, userId);
2529                     sortResult = true;
2530                 } else {
2531                     // If not web Intent, just add result to candidate set and let ResolverActivity
2532                     // figure it out.
2533                     if (specificXpInfo != null) {
2534                         result.add(specificXpInfo.resolveInfo);
2535                         sortResult = true;
2536                     }
2537                 }
2538             } else {
2539                 final PackageSetting setting =
2540                         getPackageSettingInternal(pkgName, Process.SYSTEM_UID);
2541                 result = null;
2542                 if (setting != null && setting.pkg != null && (resolveForStart
2543                         || !shouldFilterApplicationLocked(setting, filterCallingUid, userId))) {
2544                     result = filterIfNotSystemUser(mComponentResolver.queryActivities(
2545                             intent, resolvedType, flags, setting.pkg.getActivities(), userId),
2546                             userId);
2547                 }
2548                 if (result == null || result.size() == 0) {
2549                     // the caller wants to resolve for a particular package; however, there
2550                     // were no installed results, so, try to find an ephemeral result
2551                     addInstant = isInstantAppResolutionAllowed(intent, null /*result*/, userId,
2552                             true /*skipPackageCheck*/, flags);
2553                     if (result == null) {
2554                         result = new ArrayList<>();
2555                     }
2556                 }
2557             }
2558             return new QueryIntentActivitiesResult(sortResult, addInstant, result);
2559         }
2560 
2561         /**
2562          * Returns the activity component that can handle install failures.
2563          * <p>By default, the instant application installer handles failures. However, an
2564          * application may want to handle failures on its own. Applications do this by
2565          * creating an activity with an intent filter that handles the action
2566          * {@link Intent#ACTION_INSTALL_FAILURE}.
2567          */
findInstallFailureActivity( String packageName, int filterCallingUid, int userId)2568         private @Nullable ComponentName findInstallFailureActivity(
2569                 String packageName, int filterCallingUid, int userId) {
2570             final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
2571             failureActivityIntent.setPackage(packageName);
2572             // IMPORTANT: disallow dynamic splits to avoid an infinite loop
2573             final List<ResolveInfo> result = queryIntentActivitiesInternal(
2574                     failureActivityIntent, null /*resolvedType*/, 0 /*flags*/,
2575                     0 /*privateResolveFlags*/, filterCallingUid, userId, false /*resolveForStart*/,
2576                     false /*allowDynamicSplits*/);
2577             final int NR = result.size();
2578             if (NR > 0) {
2579                 for (int i = 0; i < NR; i++) {
2580                     final ResolveInfo info = result.get(i);
2581                     if (info.activityInfo.splitName != null) {
2582                         continue;
2583                     }
2584                     return new ComponentName(packageName, info.activityInfo.name);
2585                 }
2586             }
2587             return null;
2588         }
2589 
getActivityInfo(ComponentName component, int flags, int userId)2590         public final ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2591             return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
2592         }
2593 
2594         /**
2595          * Important: The provided filterCallingUid is used exclusively to filter out activities
2596          * that can be seen based on user state. It's typically the original caller uid prior
2597          * to clearing. Because it can only be provided by trusted code, its value can be
2598          * trusted and will be used as-is; unlike userId which will be validated by this method.
2599          */
getActivityInfoInternal(ComponentName component, int flags, int filterCallingUid, int userId)2600         public final ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
2601                 int filterCallingUid, int userId) {
2602             if (!mUserManager.exists(userId)) return null;
2603             flags = updateFlagsForComponent(flags, userId);
2604 
2605             if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
2606                 enforceCrossUserPermission(Binder.getCallingUid(), userId,
2607                         false /* requireFullPermission */, false /* checkShell */,
2608                         "get activity info");
2609             }
2610 
2611             return getActivityInfoInternalBody(component, flags, filterCallingUid, userId);
2612         }
2613 
getActivityInfoInternalBody(ComponentName component, int flags, int filterCallingUid, int userId)2614         protected ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags,
2615                 int filterCallingUid, int userId) {
2616             ParsedActivity a = mComponentResolver.getActivity(component);
2617 
2618             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2619 
2620             AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName());
2621             if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
2622                 PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
2623                 if (ps == null) return null;
2624                 if (shouldFilterApplicationLocked(
2625                         ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
2626                     return null;
2627                 }
2628                 return PackageInfoUtils.generateActivityInfo(pkg,
2629                         a, flags, ps.readUserState(userId), userId, ps);
2630             }
2631             if (resolveComponentName().equals(component)) {
2632                 return PackageParser.generateActivityInfo(
2633                         mResolveActivity, flags, new PackageUserState(), userId);
2634             }
2635             return null;
2636         }
2637 
getPackage(String packageName)2638         public AndroidPackage getPackage(String packageName) {
2639             packageName = resolveInternalPackageNameLPr(
2640                     packageName, PackageManager.VERSION_CODE_HIGHEST);
2641             return mPackages.get(packageName);
2642         }
2643 
getPackage(int uid)2644         public AndroidPackage getPackage(int uid) {
2645             final String[] packageNames = getPackagesForUidInternal(uid, Process.SYSTEM_UID);
2646             AndroidPackage pkg = null;
2647             final int numPackages = packageNames == null ? 0 : packageNames.length;
2648             for (int i = 0; pkg == null && i < numPackages; i++) {
2649                 pkg = mPackages.get(packageNames[i]);
2650             }
2651             return pkg;
2652         }
2653 
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int filterCallingUid, int userId)2654         public final ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName,
2655                 int flags, int filterCallingUid, int userId) {
2656             if (!mUserManager.exists(userId)) return null;
2657             PackageSetting ps = mSettings.getPackageLPr(packageName);
2658             if (ps != null) {
2659                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
2660                     return null;
2661                 }
2662                 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
2663                     return null;
2664                 }
2665                 if (ps.pkg == null) {
2666                     final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
2667                     if (pInfo != null) {
2668                         return pInfo.applicationInfo;
2669                     }
2670                     return null;
2671                 }
2672                 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, flags,
2673                         ps.readUserState(userId), userId, ps);
2674                 if (ai != null) {
2675                     ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
2676                 }
2677                 return ai;
2678             }
2679             return null;
2680         }
2681 
getApplicationInfo(String packageName, int flags, int userId)2682         public final ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2683             return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
2684         }
2685 
2686         /**
2687          * Important: The provided filterCallingUid is used exclusively to filter out applications
2688          * that can be seen based on user state. It's typically the original caller uid prior
2689          * to clearing. Because it can only be provided by trusted code, its value can be
2690          * trusted and will be used as-is; unlike userId which will be validated by this method.
2691          */
getApplicationInfoInternal(String packageName, int flags, int filterCallingUid, int userId)2692         public final ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
2693                 int filterCallingUid, int userId) {
2694             if (!mUserManager.exists(userId)) return null;
2695             flags = updateFlagsForApplication(flags, userId);
2696 
2697             if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
2698                 enforceCrossUserPermission(Binder.getCallingUid(), userId,
2699                         false /* requireFullPermission */, false /* checkShell */,
2700                         "get application info");
2701             }
2702 
2703             return getApplicationInfoInternalBody(packageName, flags, filterCallingUid, userId);
2704         }
2705 
getApplicationInfoInternalBody(String packageName, int flags, int filterCallingUid, int userId)2706         protected ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags,
2707                 int filterCallingUid, int userId) {
2708             // writer
2709             // Normalize package name to handle renamed packages and static libs
2710             packageName = resolveInternalPackageNameLPr(packageName,
2711                     PackageManager.VERSION_CODE_HIGHEST);
2712 
2713             AndroidPackage p = mPackages.get(packageName);
2714             if (DEBUG_PACKAGE_INFO) Log.v(
2715                     TAG, "getApplicationInfo " + packageName
2716                     + ": " + p);
2717             if (p != null) {
2718                 PackageSetting ps = mSettings.getPackageLPr(packageName);
2719                 if (ps == null) return null;
2720                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
2721                     return null;
2722                 }
2723                 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
2724                     return null;
2725                 }
2726                 // Note: isEnabledLP() does not apply here - always return info
2727                 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(
2728                         p, flags, ps.readUserState(userId), userId, ps);
2729                 if (ai != null) {
2730                     ai.packageName = resolveExternalPackageNameLPr(p);
2731                 }
2732                 return ai;
2733             }
2734             if ((flags & PackageManager.MATCH_APEX) != 0) {
2735                 // For APKs, PackageInfo.applicationInfo is not exactly the same as ApplicationInfo
2736                 // returned from getApplicationInfo, but for APEX packages difference shouldn't be
2737                 // very big.
2738                 // TODO(b/155328545): generate proper application info for APEXes as well.
2739                 int apexFlags = ApexManager.MATCH_ACTIVE_PACKAGE;
2740                 if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
2741                     apexFlags = ApexManager.MATCH_FACTORY_PACKAGE;
2742                 }
2743                 final PackageInfo pi = mApexManager.getPackageInfo(packageName, apexFlags);
2744                 if (pi == null) {
2745                     return null;
2746                 }
2747                 return pi.applicationInfo;
2748             }
2749             if ("android".equals(packageName)||"system".equals(packageName)) {
2750                 return androidApplication();
2751             }
2752             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
2753                 // Already generates the external package name
2754                 return generateApplicationInfoFromSettingsLPw(packageName,
2755                         flags, filterCallingUid, userId);
2756             }
2757             return null;
2758         }
2759 
filterCandidatesWithDomainPreferredActivitiesLPrBody( Intent intent, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug)2760         protected ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody(
2761                 Intent intent, int matchFlags, List<ResolveInfo> candidates,
2762                 CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug) {
2763             final ArrayList<ResolveInfo> result = new ArrayList<>();
2764             final ArrayList<ResolveInfo> matchAllList = new ArrayList<>();
2765             final ArrayList<ResolveInfo> undefinedList = new ArrayList<>();
2766 
2767             // Blocking instant apps is usually done in applyPostResolutionFilter, but since
2768             // domain verification can resolve to a single result, which can be an instant app,
2769             // it will then be filtered to an empty list in that method. Instead, do blocking
2770             // here so that instant apps can be ignored for approval filtering and a lower
2771             // priority result chosen instead.
2772             final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
2773 
2774             final int count = candidates.size();
2775             // First, try to use approved apps.
2776             for (int n = 0; n < count; n++) {
2777                 ResolveInfo info = candidates.get(n);
2778                 if (blockInstant && (info.isInstantAppAvailable
2779                         || isInstantApp(info.activityInfo.packageName, userId))) {
2780                     continue;
2781                 }
2782 
2783                 // Add to the special match all list (Browser use case)
2784                 if (info.handleAllWebDataURI) {
2785                     matchAllList.add(info);
2786                 } else {
2787                     undefinedList.add(info);
2788                 }
2789             }
2790 
2791             // We'll want to include browser possibilities in a few cases
2792             boolean includeBrowser = false;
2793 
2794             if (!DomainVerificationUtils.isDomainVerificationIntent(intent, matchFlags)) {
2795                 result.addAll(undefinedList);
2796                 // Maybe add one for the other profile.
2797                 if (xpDomainInfo != null && xpDomainInfo.highestApprovalLevel
2798                         > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE) {
2799                     result.add(xpDomainInfo.resolveInfo);
2800                 }
2801                 includeBrowser = true;
2802             } else {
2803                 Pair<List<ResolveInfo>, Integer> infosAndLevel = mDomainVerificationManager
2804                         .filterToApprovedApp(intent, undefinedList, userId,
2805                                 mSettings::getPackageLPr);
2806                 List<ResolveInfo> approvedInfos = infosAndLevel.first;
2807                 Integer highestApproval = infosAndLevel.second;
2808 
2809                 // If no apps are approved for the domain, resolve only to browsers
2810                 if (approvedInfos.isEmpty()) {
2811                     includeBrowser = true;
2812                     if (xpDomainInfo != null && xpDomainInfo.highestApprovalLevel
2813                             > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE) {
2814                         result.add(xpDomainInfo.resolveInfo);
2815                     }
2816                 } else {
2817                     result.addAll(approvedInfos);
2818 
2819                     // If the other profile has an app that's higher approval, add it
2820                     if (xpDomainInfo != null
2821                             && xpDomainInfo.highestApprovalLevel > highestApproval) {
2822                         result.add(xpDomainInfo.resolveInfo);
2823                     }
2824                 }
2825             }
2826 
2827             if (includeBrowser) {
2828                 // Also add browsers (all of them or only the default one)
2829                 if (DEBUG_DOMAIN_VERIFICATION) {
2830                     Slog.v(TAG, "   ...including browsers in candidate set");
2831                 }
2832                 if ((matchFlags & MATCH_ALL) != 0) {
2833                     result.addAll(matchAllList);
2834                 } else {
2835                     // Browser/generic handling case.  If there's a default browser, go straight
2836                     // to that (but only if there is no other higher-priority match).
2837                     final String defaultBrowserPackageName = mDefaultAppProvider.getDefaultBrowser(
2838                             userId);
2839                     int maxMatchPrio = 0;
2840                     ResolveInfo defaultBrowserMatch = null;
2841                     final int numCandidates = matchAllList.size();
2842                     for (int n = 0; n < numCandidates; n++) {
2843                         ResolveInfo info = matchAllList.get(n);
2844                         // track the highest overall match priority...
2845                         if (info.priority > maxMatchPrio) {
2846                             maxMatchPrio = info.priority;
2847                         }
2848                         // ...and the highest-priority default browser match
2849                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
2850                             if (defaultBrowserMatch == null
2851                                     || (defaultBrowserMatch.priority < info.priority)) {
2852                                 if (debug) {
2853                                     Slog.v(TAG, "Considering default browser match " + info);
2854                                 }
2855                                 defaultBrowserMatch = info;
2856                             }
2857                         }
2858                     }
2859                     if (defaultBrowserMatch != null
2860                             && defaultBrowserMatch.priority >= maxMatchPrio
2861                             && !TextUtils.isEmpty(defaultBrowserPackageName))
2862                     {
2863                         if (debug) {
2864                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
2865                         }
2866                         result.add(defaultBrowserMatch);
2867                     } else {
2868                         result.addAll(matchAllList);
2869                     }
2870                 }
2871 
2872                 // If there is nothing selected, add all candidates
2873                 if (result.size() == 0) {
2874                     result.addAll(candidates);
2875                 }
2876             }
2877             return result;
2878         }
2879 
2880         /**
2881          * Report the 'Home' activity which is currently set as "always use this one". If non is set
2882          * then reports the most likely home activity or null if there are more than one.
2883          */
getDefaultHomeActivity(int userId)2884         public final ComponentName getDefaultHomeActivity(int userId) {
2885             List<ResolveInfo> allHomeCandidates = new ArrayList<>();
2886             ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
2887             if (cn != null) {
2888                 return cn;
2889             }
2890             // TODO: This should not happen since there should always be a default package set for
2891             //  ROLE_HOME in RoleManager. Continue with a warning log for now.
2892             Slog.w(TAG, "Default package for ROLE_HOME is not set in RoleManager");
2893 
2894             // Find the launcher with the highest priority and return that component if there are no
2895             // other home activity with the same priority.
2896             int lastPriority = Integer.MIN_VALUE;
2897             ComponentName lastComponent = null;
2898             final int size = allHomeCandidates.size();
2899             for (int i = 0; i < size; i++) {
2900                 final ResolveInfo ri = allHomeCandidates.get(i);
2901                 if (ri.priority > lastPriority) {
2902                     lastComponent = ri.activityInfo.getComponentName();
2903                     lastPriority = ri.priority;
2904                 } else if (ri.priority == lastPriority) {
2905                     // Two components found with same priority.
2906                     lastComponent = null;
2907                 }
2908             }
2909             return lastComponent;
2910         }
2911 
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)2912         public final ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
2913                 int userId) {
2914             Intent intent  = getHomeIntent();
2915             List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
2916                     PackageManager.GET_META_DATA, userId);
2917             allHomeCandidates.clear();
2918             if (resolveInfos == null) {
2919                 return null;
2920             }
2921             allHomeCandidates.addAll(resolveInfos);
2922 
2923             String packageName = mDefaultAppProvider.getDefaultHome(userId);
2924             if (packageName == null) {
2925                 // Role changes are not and cannot be atomic because its implementation lives inside
2926                 // a system app, so when the home role changes, there is a window when the previous
2927                 // role holder is removed and the new role holder is granted the preferred activity,
2928                 // but hasn't become the role holder yet. However, this case may be easily hit
2929                 // because the preferred activity change triggers a broadcast and receivers may try
2930                 // to get the default home activity there. So we need to fix it for this time
2931                 // window, and an easy workaround is to fallback to the current preferred activity.
2932                 final int appId = UserHandle.getAppId(Binder.getCallingUid());
2933                 final boolean filtered = appId >= Process.FIRST_APPLICATION_UID;
2934                 FindPreferredActivityBodyResult result = findPreferredActivityInternal(
2935                         intent, null, 0, resolveInfos, true, false, false, userId, filtered);
2936                 ResolveInfo preferredResolveInfo =  result.mPreferredResolveInfo;
2937                 if (preferredResolveInfo != null && preferredResolveInfo.activityInfo != null) {
2938                     packageName = preferredResolveInfo.activityInfo.packageName;
2939                 }
2940             }
2941             if (packageName == null) {
2942                 return null;
2943             }
2944 
2945             int resolveInfosSize = resolveInfos.size();
2946             for (int i = 0; i < resolveInfosSize; i++) {
2947                 ResolveInfo resolveInfo = resolveInfos.get(i);
2948 
2949                 if (resolveInfo.activityInfo != null && TextUtils.equals(
2950                         resolveInfo.activityInfo.packageName, packageName)) {
2951                     return new ComponentName(resolveInfo.activityInfo.packageName,
2952                             resolveInfo.activityInfo.name);
2953                 }
2954             }
2955             return null;
2956         }
2957 
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)2958         public final CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
2959                 String resolvedType, int flags, int sourceUserId, int parentUserId) {
2960             if (!mUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
2961                     sourceUserId)) {
2962                 return null;
2963             }
2964             List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
2965                     resolvedType, flags, parentUserId);
2966 
2967             if (resultTargetUser == null || resultTargetUser.isEmpty()) {
2968                 return null;
2969             }
2970             CrossProfileDomainInfo result = null;
2971             int size = resultTargetUser.size();
2972             for (int i = 0; i < size; i++) {
2973                 ResolveInfo riTargetUser = resultTargetUser.get(i);
2974                 // Intent filter verification is only for filters that specify a host. So don't
2975                 //return
2976                 // those that handle all web uris.
2977                 if (riTargetUser.handleAllWebDataURI) {
2978                     continue;
2979                 }
2980                 String packageName = riTargetUser.activityInfo.packageName;
2981                 PackageSetting ps = mSettings.getPackageLPr(packageName);
2982                 if (ps == null) {
2983                     continue;
2984                 }
2985 
2986                 int approvalLevel = mDomainVerificationManager
2987                         .approvalLevelForDomain(ps, intent, flags, parentUserId);
2988 
2989                 if (result == null) {
2990                     result = new CrossProfileDomainInfo(createForwardingResolveInfoUnchecked(
2991                             new WatchedIntentFilter(), sourceUserId, parentUserId), approvalLevel);
2992                 } else {
2993                     result.highestApprovalLevel =
2994                             Math.max(approvalLevel, result.highestApprovalLevel);
2995                 }
2996             }
2997             if (result != null && result.highestApprovalLevel
2998                     <= DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE) {
2999                 return null;
3000             }
3001             return result;
3002         }
3003 
getHomeIntent()3004         public final Intent getHomeIntent() {
3005             Intent intent = new Intent(Intent.ACTION_MAIN);
3006             intent.addCategory(Intent.CATEGORY_HOME);
3007             intent.addCategory(Intent.CATEGORY_DEFAULT);
3008             return intent;
3009         }
3010 
getMatchingCrossProfileIntentFilters( Intent intent, String resolvedType, int userId)3011         public final List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(
3012                 Intent intent, String resolvedType, int userId) {
3013             CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolver(userId);
3014             if (resolver != null) {
3015                 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
3016             }
3017             return null;
3018         }
3019 
3020         /**
3021          * Filters out ephemeral activities.
3022          * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
3023          * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
3024          *
3025          * @param resolveInfos The pre-filtered list of resolved activities
3026          * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
3027          *          is performed.
3028          * @param intent
3029          * @return A filtered list of resolved activities.
3030          */
applyPostResolutionFilter( @onNull List<ResolveInfo> resolveInfos, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, boolean resolveForStart, int userId, Intent intent)3031         public final List<ResolveInfo> applyPostResolutionFilter(
3032                 @NonNull List<ResolveInfo> resolveInfos,
3033                 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
3034                 boolean resolveForStart, int userId, Intent intent) {
3035             final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
3036             for (int i = resolveInfos.size() - 1; i >= 0; i--) {
3037                 final ResolveInfo info = resolveInfos.get(i);
3038                 // remove locally resolved instant app web results when disabled
3039                 if (info.isInstantAppAvailable && blockInstant) {
3040                     resolveInfos.remove(i);
3041                     continue;
3042                 }
3043                 // allow activities that are defined in the provided package
3044                 if (allowDynamicSplits
3045                         && info.activityInfo != null
3046                         && info.activityInfo.splitName != null
3047                         && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
3048                                 info.activityInfo.splitName)) {
3049                     if (instantAppInstallerActivity() == null) {
3050                         if (DEBUG_INSTALL) {
3051                             Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
3052                         }
3053                         resolveInfos.remove(i);
3054                         continue;
3055                     }
3056                     if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
3057                         resolveInfos.remove(i);
3058                         continue;
3059                     }
3060                     // requested activity is defined in a split that hasn't been installed yet.
3061                     // add the installer to the resolve list
3062                     if (DEBUG_INSTALL) {
3063                         Slog.v(TAG, "Adding installer to the ResolveInfo list");
3064                     }
3065                     final ResolveInfo installerInfo = new ResolveInfo(
3066                             mInstantAppInstallerInfo);
3067                     final ComponentName installFailureActivity = findInstallFailureActivity(
3068                             info.activityInfo.packageName,  filterCallingUid, userId);
3069                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
3070                             installFailureActivity,
3071                             info.activityInfo.packageName,
3072                             info.activityInfo.applicationInfo.longVersionCode,
3073                             info.activityInfo.splitName);
3074                     // add a non-generic filter
3075                     installerInfo.filter = new IntentFilter();
3076 
3077                     // This resolve info may appear in the chooser UI, so let us make it
3078                     // look as the one it replaces as far as the user is concerned which
3079                     // requires loading the correct label and icon for the resolve info.
3080                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
3081                     installerInfo.labelRes = info.resolveLabelResId();
3082                     installerInfo.icon = info.resolveIconResId();
3083                     installerInfo.isInstantAppAvailable = true;
3084                     resolveInfos.set(i, installerInfo);
3085                     continue;
3086                 }
3087                 if (ephemeralPkgName == null) {
3088                     // caller is a full app
3089                     SettingBase callingSetting =
3090                             mSettings.getSettingLPr(UserHandle.getAppId(filterCallingUid));
3091                     PackageSetting resolvedSetting =
3092                             getPackageSettingInternal(info.activityInfo.packageName, 0);
3093                     if (resolveForStart
3094                             || !mAppsFilter.shouldFilterApplication(
3095                                     filterCallingUid, callingSetting, resolvedSetting, userId)) {
3096                         continue;
3097                     }
3098                 } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
3099                     // caller is same app; don't need to apply any other filtering
3100                     continue;
3101                 } else if (resolveForStart
3102                         && (intent.isWebIntent()
3103                                 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0)
3104                         && intent.getPackage() == null
3105                         && intent.getComponent() == null) {
3106                     // ephemeral apps can launch other ephemeral apps indirectly
3107                     continue;
3108                 } else if (((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP)
3109                                 != 0)
3110                         && !info.activityInfo.applicationInfo.isInstantApp()) {
3111                     // allow activities that have been explicitly exposed to ephemeral apps
3112                     continue;
3113                 }
3114                 resolveInfos.remove(i);
3115             }
3116             return resolveInfos;
3117         }
3118 
applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos, String instantAppPkgName, @UserIdInt int userId, int filterCallingUid)3119         private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
3120                 String instantAppPkgName, @UserIdInt int userId, int filterCallingUid) {
3121             for (int i = resolveInfos.size() - 1; i >= 0; i--) {
3122                 final ResolveInfo info = resolveInfos.get(i);
3123                 if (instantAppPkgName == null) {
3124                     SettingBase callingSetting =
3125                             mSettings.getSettingLPr(UserHandle.getAppId(filterCallingUid));
3126                     PackageSetting resolvedSetting =
3127                             getPackageSettingInternal(info.serviceInfo.packageName, 0);
3128                     if (!mAppsFilter.shouldFilterApplication(
3129                             filterCallingUid, callingSetting, resolvedSetting, userId)) {
3130                         continue;
3131                     }
3132                 }
3133                 final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
3134                 // allow services that are defined in the provided package
3135                 if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
3136                     if (info.serviceInfo.splitName != null
3137                             && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
3138                                     info.serviceInfo.splitName)) {
3139                         if (instantAppInstallerActivity() == null) {
3140                             if (DEBUG_INSTANT) {
3141                                 Slog.v(TAG, "No installer - not adding it to the ResolveInfo"
3142                                         + "list");
3143                             }
3144                             resolveInfos.remove(i);
3145                             continue;
3146                         }
3147                         // requested service is defined in a split that hasn't been installed yet.
3148                         // add the installer to the resolve list
3149                         if (DEBUG_INSTANT) {
3150                             Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
3151                         }
3152                         final ResolveInfo installerInfo = new ResolveInfo(
3153                                 mInstantAppInstallerInfo);
3154                         installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
3155                                 null /* installFailureActivity */,
3156                                 info.serviceInfo.packageName,
3157                                 info.serviceInfo.applicationInfo.longVersionCode,
3158                                 info.serviceInfo.splitName);
3159                         // add a non-generic filter
3160                         installerInfo.filter = new IntentFilter();
3161                         // load resources from the correct package
3162                         installerInfo.resolvePackageName = info.getComponentInfo().packageName;
3163                         resolveInfos.set(i, installerInfo);
3164                     }
3165                     continue;
3166                 }
3167                 // allow services that have been explicitly exposed to ephemeral apps
3168                 if (!isEphemeralApp
3169                         && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP)
3170                                 != 0)) {
3171                     continue;
3172                 }
3173                 resolveInfos.remove(i);
3174             }
3175             return resolveInfos;
3176         }
3177 
filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int userId)3178         private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
3179                 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
3180                 int userId) {
3181             final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
3182 
3183             if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
3184                 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
3185                         candidates.size());
3186             }
3187 
3188             final ArrayList<ResolveInfo> result =
3189                     filterCandidatesWithDomainPreferredActivitiesLPrBody(
3190                         intent, matchFlags, candidates, xpDomainInfo, userId, debug);
3191 
3192             if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
3193                 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: "
3194                         + result.size());
3195                 for (ResolveInfo info : result) {
3196                     Slog.v(TAG, "  + " + info.activityInfo);
3197                 }
3198             }
3199             return result;
3200         }
3201 
3202         /**
3203          * Filter out activities with systemUserOnly flag set, when current user is not System.
3204          *
3205          * @return filtered list
3206          */
filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId)3207         private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos,
3208                 int userId) {
3209             if (userId == UserHandle.USER_SYSTEM) {
3210                 return resolveInfos;
3211             }
3212             for (int i = resolveInfos.size() - 1; i >= 0; i--) {
3213                 ResolveInfo info = resolveInfos.get(i);
3214                 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
3215                     resolveInfos.remove(i);
3216                 }
3217             }
3218             return resolveInfos;
3219         }
3220 
maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent, String resolvedType, int flags, int userId, boolean resolveForStart, boolean isRequesterInstantApp)3221         private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result,
3222                 Intent intent,
3223                 String resolvedType, int flags, int userId, boolean resolveForStart,
3224                 boolean isRequesterInstantApp) {
3225             // first, check to see if we've got an instant app already installed
3226             final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
3227             ResolveInfo localInstantApp = null;
3228             boolean blockResolution = false;
3229             if (!alreadyResolvedLocally) {
3230                 final List<ResolveInfo> instantApps = mComponentResolver.queryActivities(
3231                         intent,
3232                         resolvedType,
3233                         flags
3234                             | PackageManager.GET_RESOLVED_FILTER
3235                             | PackageManager.MATCH_INSTANT
3236                             | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
3237                         userId);
3238                 for (int i = instantApps.size() - 1; i >= 0; --i) {
3239                     final ResolveInfo info = instantApps.get(i);
3240                     final String packageName = info.activityInfo.packageName;
3241                     final PackageSetting ps = mSettings.getPackageLPr(packageName);
3242                     if (ps.getInstantApp(userId)) {
3243                         if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags,
3244                                 userId)) {
3245                             if (DEBUG_INSTANT) {
3246                                 Slog.v(TAG, "Instant app approved for intent; pkg: "
3247                                         + packageName);
3248                             }
3249                             localInstantApp = info;
3250                         } else {
3251                             if (DEBUG_INSTANT) {
3252                                 Slog.v(TAG, "Instant app not approved for intent; pkg: "
3253                                         + packageName);
3254                             }
3255                             blockResolution = true;
3256                         }
3257                         break;
3258                     }
3259                 }
3260             }
3261             // no app installed, let's see if one's available
3262             AuxiliaryResolveInfo auxiliaryResponse = null;
3263             if (!blockResolution) {
3264                 if (localInstantApp == null) {
3265                     // we don't have an instant app locally, resolve externally
3266                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
3267                     String token = UUID.randomUUID().toString();
3268                     InstantAppDigest digest = InstantAppResolver.parseDigest(intent);
3269                     final InstantAppRequest requestObject =
3270                             new InstantAppRequest(null /*responseObj*/,
3271                             intent /*origIntent*/, resolvedType, null /*callingPackage*/,
3272                             null /*callingFeatureId*/, isRequesterInstantApp, userId,
3273                             null /*verificationBundle*/, resolveForStart,
3274                             digest.getDigestPrefixSecure(), token);
3275                     auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
3276                             mInstantAppResolverConnection, requestObject);
3277                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3278                 } else {
3279                     // we have an instant application locally, but, we can't admit that since
3280                     // callers shouldn't be able to determine prior browsing. create a placeholder
3281                     // auxiliary response so the downstream code behaves as if there's an
3282                     // instant application available externally. when it comes time to start
3283                     // the instant application, we'll do the right thing.
3284                     final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
3285                     auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
3286                                             ai.packageName, ai.longVersionCode,
3287                             null /* splitName */);
3288                 }
3289             }
3290             if (intent.isWebIntent() && auxiliaryResponse == null) {
3291                 return result;
3292             }
3293             final PackageSetting ps =
3294                     mSettings.getPackageLPr(instantAppInstallerActivity().packageName);
3295             if (ps == null
3296                     || !ps.readUserState(userId).isEnabled(instantAppInstallerActivity(), 0)) {
3297                 return result;
3298             }
3299             final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
3300             ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
3301                     instantAppInstallerActivity(), 0, ps.readUserState(userId), userId);
3302             ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
3303                     | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
3304             // add a non-generic filter
3305             ephemeralInstaller.filter = new IntentFilter();
3306             if (intent.getAction() != null) {
3307                 ephemeralInstaller.filter.addAction(intent.getAction());
3308             }
3309             if (intent.getData() != null && intent.getData().getPath() != null) {
3310                 ephemeralInstaller.filter.addDataPath(
3311                         intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
3312             }
3313             ephemeralInstaller.isInstantAppAvailable = true;
3314             // make sure this resolver is the default
3315             ephemeralInstaller.isDefault = true;
3316             ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
3317             if (DEBUG_INSTANT) {
3318                 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
3319             }
3320 
3321             result.add(ephemeralInstaller);
3322             return result;
3323         }
3324 
generatePackageInfo(PackageSetting ps, int flags, int userId)3325         public final PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3326             if (!mUserManager.exists(userId)) return null;
3327             if (ps == null) {
3328                 return null;
3329             }
3330             final int callingUid = Binder.getCallingUid();
3331             // Filter out ephemeral app metadata:
3332             //   * The system/shell/root can see metadata for any app
3333             //   * An installed app can see metadata for 1) other installed apps
3334             //     and 2) ephemeral apps that have explicitly interacted with it
3335             //   * Ephemeral apps can only see their own data and exposed installed apps
3336             //   * Holding a signature permission allows seeing instant apps
3337             if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
3338                 return null;
3339             }
3340 
3341             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3342                     && ps.isSystem()) {
3343                 flags |= MATCH_ANY_USER;
3344             }
3345 
3346             final PackageUserState state = ps.readUserState(userId);
3347             AndroidPackage p = ps.pkg;
3348             if (p != null) {
3349                 // Compute GIDs only if requested
3350                 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY
3351                         : mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId));
3352                 // Compute granted permissions only if package has requested permissions
3353                 final Set<String> permissions = ((flags & PackageManager.GET_PERMISSIONS) == 0
3354                         || ArrayUtils.isEmpty(p.getRequestedPermissions())) ? Collections.emptySet()
3355                         : mPermissionManager.getGrantedPermissions(ps.name, userId);
3356 
3357                 PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags,
3358                         ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId, ps);
3359 
3360                 if (packageInfo == null) {
3361                     return null;
3362                 }
3363 
3364                 packageInfo.packageName = packageInfo.applicationInfo.packageName =
3365                         resolveExternalPackageNameLPr(p);
3366 
3367                 return packageInfo;
3368             } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
3369                 PackageInfo pi = new PackageInfo();
3370                 pi.packageName = ps.name;
3371                 pi.setLongVersionCode(ps.versionCode);
3372                 pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
3373                 pi.firstInstallTime = ps.firstInstallTime;
3374                 pi.lastUpdateTime = ps.lastUpdateTime;
3375 
3376                 ApplicationInfo ai = new ApplicationInfo();
3377                 ai.packageName = ps.name;
3378                 ai.uid = UserHandle.getUid(userId, ps.appId);
3379                 ai.primaryCpuAbi = ps.primaryCpuAbiString;
3380                 ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
3381                 ai.setVersionCode(ps.versionCode);
3382                 ai.flags = ps.pkgFlags;
3383                 ai.privateFlags = ps.pkgPrivateFlags;
3384                 pi.applicationInfo =
3385                         PackageParser.generateApplicationInfo(ai, flags, state, userId);
3386 
3387                 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
3388                         + ps.name + "]. Provides a minimum info.");
3389                 return pi;
3390             } else {
3391                 return null;
3392             }
3393         }
3394 
getPackageInfo(String packageName, int flags, int userId)3395         public final PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3396             return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3397                     flags, Binder.getCallingUid(), userId);
3398         }
3399 
3400         /**
3401          * Important: The provided filterCallingUid is used exclusively to filter out packages
3402          * that can be seen based on user state. It's typically the original caller uid prior
3403          * to clearing. Because it can only be provided by trusted code, its value can be
3404          * trusted and will be used as-is; unlike userId which will be validated by this method.
3405          */
getPackageInfoInternal(String packageName, long versionCode, int flags, int filterCallingUid, int userId)3406         public final PackageInfo getPackageInfoInternal(String packageName, long versionCode,
3407                 int flags, int filterCallingUid, int userId) {
3408             if (!mUserManager.exists(userId)) return null;
3409             flags = updateFlagsForPackage(flags, userId);
3410             enforceCrossUserPermission(Binder.getCallingUid(), userId,
3411                     false /* requireFullPermission */, false /* checkShell */, "get package info");
3412 
3413             return getPackageInfoInternalBody(packageName, versionCode, flags, filterCallingUid,
3414                     userId);
3415         }
3416 
getPackageInfoInternalBody(String packageName, long versionCode, int flags, int filterCallingUid, int userId)3417         protected PackageInfo getPackageInfoInternalBody(String packageName, long versionCode,
3418                 int flags, int filterCallingUid, int userId) {
3419             // reader
3420             // Normalize package name to handle renamed packages and static libs
3421             packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3422 
3423             final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3424             if (matchFactoryOnly) {
3425                 // Instant app filtering for APEX modules is ignored
3426                 if ((flags & MATCH_APEX) != 0) {
3427                     return mApexManager.getPackageInfo(packageName,
3428                             ApexManager.MATCH_FACTORY_PACKAGE);
3429                 }
3430                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3431                 if (ps != null) {
3432                     if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3433                         return null;
3434                     }
3435                     if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
3436                         return null;
3437                     }
3438                     return generatePackageInfo(ps, flags, userId);
3439                 }
3440             }
3441 
3442             AndroidPackage p = mPackages.get(packageName);
3443             if (matchFactoryOnly && p != null && !p.isSystem()) {
3444                 return null;
3445             }
3446             if (DEBUG_PACKAGE_INFO)
3447                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3448             if (p != null) {
3449                 final PackageSetting ps = getPackageSetting(p.getPackageName());
3450                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3451                     return null;
3452                 }
3453                 if (ps != null && shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
3454                     return null;
3455                 }
3456 
3457                 return generatePackageInfo(ps, flags, userId);
3458             }
3459             if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3460                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
3461                 if (ps == null) return null;
3462                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3463                     return null;
3464                 }
3465                 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
3466                     return null;
3467                 }
3468                 return generatePackageInfo(ps, flags, userId);
3469             }
3470             if ((flags & MATCH_APEX) != 0) {
3471                 return mApexManager.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
3472             }
3473             return null;
3474         }
3475 
3476         @Nullable
getPackageSetting(String packageName)3477         public final PackageSetting getPackageSetting(String packageName) {
3478             return getPackageSettingInternal(packageName, Binder.getCallingUid());
3479         }
3480 
getPackageSettingInternal(String packageName, int callingUid)3481         public PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
3482             packageName = resolveInternalPackageNameInternalLocked(
3483                     packageName, PackageManager.VERSION_CODE_HIGHEST, callingUid);
3484             return mSettings.getPackageLPr(packageName);
3485         }
3486 
getInstalledPackages(int flags, int userId)3487         public final ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3488             final int callingUid = Binder.getCallingUid();
3489             if (getInstantAppPackageName(callingUid) != null) {
3490                 return ParceledListSlice.emptyList();
3491             }
3492             if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
3493             flags = updateFlagsForPackage(flags, userId);
3494 
3495             enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
3496                     false /* checkShell */, "get installed packages");
3497 
3498             return getInstalledPackagesBody(flags, userId, callingUid);
3499         }
3500 
getInstalledPackagesBody(int flags, int userId, int callingUid)3501         protected ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
3502                                                                           int callingUid) {
3503             // writer
3504             final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
3505             final boolean listApex = (flags & MATCH_APEX) != 0;
3506             final boolean listFactory = (flags & MATCH_FACTORY_ONLY) != 0;
3507 
3508             ArrayList<PackageInfo> list;
3509             if (listUninstalled) {
3510                 list = new ArrayList<>(mSettings.getPackagesLocked().size());
3511                 for (PackageSetting ps : mSettings.getPackagesLocked().values()) {
3512                     if (listFactory) {
3513                         if (!ps.isSystem()) {
3514                             continue;
3515                         }
3516                         PackageSetting psDisabled = mSettings.getDisabledSystemPkgLPr(ps);
3517                         if (psDisabled != null) {
3518                             ps = psDisabled;
3519                         }
3520                     }
3521                     if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3522                         continue;
3523                     }
3524                     if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
3525                         continue;
3526                     }
3527                     final PackageInfo pi = generatePackageInfo(ps, flags, userId);
3528                     if (pi != null) {
3529                         list.add(pi);
3530                     }
3531                 }
3532             } else {
3533                 list = new ArrayList<>(mPackages.size());
3534                 for (AndroidPackage p : mPackages.values()) {
3535                     PackageSetting ps = getPackageSetting(p.getPackageName());
3536                     if (listFactory) {
3537                         if (!p.isSystem()) {
3538                             continue;
3539                         }
3540                         PackageSetting psDisabled = mSettings.getDisabledSystemPkgLPr(ps);
3541                         if (psDisabled != null) {
3542                             ps = psDisabled;
3543                         }
3544                     }
3545                     if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3546                         continue;
3547                     }
3548                     if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
3549                         continue;
3550                     }
3551                     final PackageInfo pi = generatePackageInfo(ps, flags, userId);
3552                     if (pi != null) {
3553                         list.add(pi);
3554                     }
3555                 }
3556             }
3557             if (listApex) {
3558                 if (listFactory) {
3559                     list.addAll(mApexManager.getFactoryPackages());
3560                 } else {
3561                     list.addAll(mApexManager.getActivePackages());
3562                 }
3563                 if (listUninstalled) {
3564                     list.addAll(mApexManager.getInactivePackages());
3565                 }
3566             }
3567             return new ParceledListSlice<>(list);
3568         }
3569 
3570         /**
3571          * If the filter's target user can handle the intent and is enabled: a [ResolveInfo] that
3572          * will forward the intent to the filter's target user, along with the highest approval of
3573          * any handler in the target user. Otherwise, returns null.
3574          */
3575         @Nullable
createForwardingResolveInfo( @onNull CrossProfileIntentFilter filter, @NonNull Intent intent, @Nullable String resolvedType, int flags, int sourceUserId)3576         private CrossProfileDomainInfo createForwardingResolveInfo(
3577                 @NonNull CrossProfileIntentFilter filter, @NonNull Intent intent,
3578                 @Nullable String resolvedType, int flags, int sourceUserId) {
3579             int targetUserId = filter.getTargetUserId();
3580             if (!isUserEnabled(targetUserId)) {
3581                 return null;
3582             }
3583 
3584             List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
3585                     resolvedType, flags, targetUserId);
3586             if (CollectionUtils.isEmpty(resultTargetUser)) {
3587                 return null;
3588             }
3589 
3590             ResolveInfo forwardingInfo = null;
3591             for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
3592                 ResolveInfo targetUserResolveInfo = resultTargetUser.get(i);
3593                 if ((targetUserResolveInfo.activityInfo.applicationInfo.flags
3594                         & ApplicationInfo.FLAG_SUSPENDED) == 0) {
3595                     forwardingInfo = createForwardingResolveInfoUnchecked(filter, sourceUserId,
3596                             targetUserId);
3597                     break;
3598                 }
3599             }
3600 
3601             if (forwardingInfo == null) {
3602                 // If all the matches in the target profile are suspended, return null.
3603                 return null;
3604             }
3605 
3606             int highestApprovalLevel = DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE;
3607 
3608             int size = resultTargetUser.size();
3609             for (int i = 0; i < size; i++) {
3610                 ResolveInfo riTargetUser = resultTargetUser.get(i);
3611                 if (riTargetUser.handleAllWebDataURI) {
3612                     continue;
3613                 }
3614                 String packageName = riTargetUser.activityInfo.packageName;
3615                 PackageSetting ps = mSettings.getPackageLPr(packageName);
3616                 if (ps == null) {
3617                     continue;
3618                 }
3619                 highestApprovalLevel = Math.max(highestApprovalLevel, mDomainVerificationManager
3620                                 .approvalLevelForDomain(ps, intent, flags, targetUserId));
3621             }
3622 
3623             return new CrossProfileDomainInfo(forwardingInfo, highestApprovalLevel);
3624         }
3625 
createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, int sourceUserId, int targetUserId)3626         public final ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
3627                 int sourceUserId, int targetUserId) {
3628             ResolveInfo forwardingResolveInfo = new ResolveInfo();
3629             final long ident = Binder.clearCallingIdentity();
3630             boolean targetIsProfile;
3631             try {
3632                 targetIsProfile = mUserManager.getUserInfo(targetUserId).isManagedProfile();
3633             } finally {
3634                 Binder.restoreCallingIdentity(ident);
3635             }
3636             String className;
3637             if (targetIsProfile) {
3638                 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
3639             } else {
3640                 className = FORWARD_INTENT_TO_PARENT;
3641             }
3642             ComponentName forwardingActivityComponentName = new ComponentName(
3643                     androidApplication().packageName, className);
3644             ActivityInfo forwardingActivityInfo =
3645                     getActivityInfo(forwardingActivityComponentName, 0,
3646                     sourceUserId);
3647             if (!targetIsProfile) {
3648                 forwardingActivityInfo.showUserIcon = targetUserId;
3649                 forwardingResolveInfo.noResourceId = true;
3650             }
3651             forwardingResolveInfo.activityInfo = forwardingActivityInfo;
3652             forwardingResolveInfo.priority = 0;
3653             forwardingResolveInfo.preferredOrder = 0;
3654             forwardingResolveInfo.match = 0;
3655             forwardingResolveInfo.isDefault = true;
3656             forwardingResolveInfo.filter = new IntentFilter(filter.getIntentFilter());
3657             forwardingResolveInfo.targetUserId = targetUserId;
3658             return forwardingResolveInfo;
3659         }
3660 
3661         // Return matching ResolveInfo in target user if any.
3662         @Nullable
queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId, boolean matchInCurrentProfile)3663         private CrossProfileDomainInfo queryCrossProfileIntents(
3664                 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3665                 int flags, int sourceUserId, boolean matchInCurrentProfile) {
3666             if (matchingFilters == null) {
3667                 return null;
3668             }
3669             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
3670             // match the same intent. For performance reasons, it is better not to
3671             // run queryIntent twice for the same userId
3672             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
3673 
3674             CrossProfileDomainInfo resultInfo = null;
3675 
3676             int size = matchingFilters.size();
3677             for (int i = 0; i < size; i++) {
3678                 CrossProfileIntentFilter filter = matchingFilters.get(i);
3679                 int targetUserId = filter.getTargetUserId();
3680                 boolean skipCurrentProfile =
3681                         (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
3682                 boolean skipCurrentProfileIfNoMatchFound =
3683                         (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
3684                 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
3685                         && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
3686                     // Checking if there are activities in the target user that can handle the
3687                     // intent.
3688                     CrossProfileDomainInfo info = createForwardingResolveInfo(filter, intent,
3689                             resolvedType, flags, sourceUserId);
3690                     if (info != null) {
3691                         resultInfo = info;
3692                         break;
3693                     }
3694                     alreadyTriedUserIds.put(targetUserId, true);
3695                 }
3696             }
3697 
3698             if (resultInfo == null) {
3699                 return null;
3700             }
3701 
3702             ResolveInfo forwardingResolveInfo = resultInfo.resolveInfo;
3703             if (!isUserEnabled(forwardingResolveInfo.targetUserId)) {
3704                 return null;
3705             }
3706 
3707             List<ResolveInfo> filteredResult =
3708                     filterIfNotSystemUser(Collections.singletonList(forwardingResolveInfo),
3709                             sourceUserId);
3710             if (filteredResult.isEmpty()) {
3711                 return null;
3712             }
3713 
3714             return resultInfo;
3715         }
3716 
querySkipCurrentProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)3717         private ResolveInfo querySkipCurrentProfileIntents(
3718                 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3719                 int flags, int sourceUserId) {
3720             if (matchingFilters != null) {
3721                 int size = matchingFilters.size();
3722                 for (int i = 0; i < size; i ++) {
3723                     CrossProfileIntentFilter filter = matchingFilters.get(i);
3724                     if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
3725                         // Checking if there are activities in the target user that can handle the
3726                         // intent.
3727                         CrossProfileDomainInfo info = createForwardingResolveInfo(filter, intent,
3728                                 resolvedType, flags, sourceUserId);
3729                         if (info != null) {
3730                             return info.resolveInfo;
3731                         }
3732                     }
3733                 }
3734             }
3735             return null;
3736         }
3737 
getServiceInfo(ComponentName component, int flags, int userId)3738         public final ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3739             if (!mUserManager.exists(userId)) return null;
3740             final int callingUid = Binder.getCallingUid();
3741             flags = updateFlagsForComponent(flags, userId);
3742             enforceCrossUserOrProfilePermission(callingUid, userId,
3743                     false /* requireFullPermission */,
3744                     false /* checkShell */, "get service info");
3745             return getServiceInfoBody(component, flags, userId, callingUid);
3746         }
3747 
getServiceInfoBody(ComponentName component, int flags, int userId, int callingUid)3748         protected ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId,
3749                                                  int callingUid) {
3750             ParsedService s = mComponentResolver.getService(component);
3751             if (DEBUG_PACKAGE_INFO) Log.v(
3752                     TAG, "getServiceInfo " + component + ": " + s);
3753             if (s == null) {
3754                 return null;
3755             }
3756 
3757             AndroidPackage pkg = mPackages.get(s.getPackageName());
3758             if (mSettings.isEnabledAndMatchLPr(pkg, s, flags, userId)) {
3759                 PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
3760                 if (ps == null) return null;
3761                 if (shouldFilterApplicationLocked(
3762                         ps, callingUid, component, TYPE_SERVICE, userId)) {
3763                     return null;
3764                 }
3765                 return PackageInfoUtils.generateServiceInfo(pkg,
3766                         s, flags, ps.readUserState(userId), userId, ps);
3767             }
3768             return null;
3769         }
3770 
3771         @Nullable
getSharedLibraryInfoLPr(String name, long version)3772         public final SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
3773             return getSharedLibraryInfo(name, version, mSharedLibraries, null);
3774         }
3775 
3776         /**
3777          * Returns the package name of the calling Uid if it's an instant app. If it isn't
3778          * instant, returns {@code null}.
3779          */
getInstantAppPackageName(int callingUid)3780         public String getInstantAppPackageName(int callingUid) {
3781             // If the caller is an isolated app use the owner's uid for the lookup.
3782             if (Process.isIsolated(callingUid)) {
3783                 callingUid = getIsolatedOwner(callingUid);
3784             }
3785             final int appId = UserHandle.getAppId(callingUid);
3786             final Object obj = mSettings.getSettingLPr(appId);
3787             if (obj instanceof PackageSetting) {
3788                 final PackageSetting ps = (PackageSetting) obj;
3789                 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
3790                 return isInstantApp ? ps.pkg.getPackageName() : null;
3791             }
3792             return null;
3793         }
3794 
3795         /**
3796          * Finds the owner for the provided isolated UID. Throws IllegalStateException if no such
3797          * isolated UID is found.
3798          */
getIsolatedOwner(int isolatedUid)3799         private int getIsolatedOwner(int isolatedUid) {
3800             final int ownerUid = mIsolatedOwners.get(isolatedUid, -1);
3801             if (ownerUid == -1) {
3802                 throw new IllegalStateException(
3803                         "No owner UID found for isolated UID " + isolatedUid);
3804             }
3805             return ownerUid;
3806         }
3807 
resolveExternalPackageNameLPr(AndroidPackage pkg)3808         public final String resolveExternalPackageNameLPr(AndroidPackage pkg) {
3809             if (pkg.getStaticSharedLibName() != null) {
3810                 return pkg.getManifestPackageName();
3811             }
3812             return pkg.getPackageName();
3813         }
3814 
resolveInternalPackageNameInternalLocked( String packageName, long versionCode, int callingUid)3815         private String resolveInternalPackageNameInternalLocked(
3816                 String packageName, long versionCode, int callingUid) {
3817             // Handle renamed packages
3818             String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
3819             packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
3820 
3821             // Is this a static library?
3822             WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
3823                     mStaticLibsByDeclaringPackage.get(packageName);
3824             if (versionedLib == null || versionedLib.size() <= 0) {
3825                 return packageName;
3826             }
3827 
3828             // Figure out which lib versions the caller can see
3829             LongSparseLongArray versionsCallerCanSee = null;
3830             final int callingAppId = UserHandle.getAppId(callingUid);
3831             if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
3832                     && callingAppId != Process.ROOT_UID) {
3833                 versionsCallerCanSee = new LongSparseLongArray();
3834                 String libName = versionedLib.valueAt(0).getName();
3835                 String[] uidPackages = getPackagesForUidInternal(callingUid, callingUid);
3836                 if (uidPackages != null) {
3837                     for (String uidPackage : uidPackages) {
3838                         PackageSetting ps = mSettings.getPackageLPr(uidPackage);
3839                         final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
3840                         if (libIdx >= 0) {
3841                             final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
3842                             versionsCallerCanSee.append(libVersion, libVersion);
3843                         }
3844                     }
3845                 }
3846             }
3847 
3848             // Caller can see nothing - done
3849             if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
3850                 return packageName;
3851             }
3852 
3853             // Find the version the caller can see and the app version code
3854             SharedLibraryInfo highestVersion = null;
3855             final int versionCount = versionedLib.size();
3856             for (int i = 0; i < versionCount; i++) {
3857                 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
3858                 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
3859                         libraryInfo.getLongVersion()) < 0) {
3860                     continue;
3861                 }
3862                 final long libVersionCode = libraryInfo.getDeclaringPackage().getLongVersionCode();
3863                 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
3864                     if (libVersionCode == versionCode) {
3865                         return libraryInfo.getPackageName();
3866                     }
3867                 } else if (highestVersion == null) {
3868                     highestVersion = libraryInfo;
3869                 } else if (libVersionCode  > highestVersion
3870                         .getDeclaringPackage().getLongVersionCode()) {
3871                     highestVersion = libraryInfo;
3872                 }
3873             }
3874 
3875             if (highestVersion != null) {
3876                 return highestVersion.getPackageName();
3877             }
3878 
3879             return packageName;
3880         }
3881 
resolveInternalPackageNameLPr(String packageName, long versionCode)3882         public final String resolveInternalPackageNameLPr(String packageName, long versionCode) {
3883             final int callingUid = Binder.getCallingUid();
3884             return resolveInternalPackageNameInternalLocked(packageName, versionCode,
3885                     callingUid);
3886         }
3887 
3888         /**
3889          * <em>IMPORTANT:</em> Not all packages returned by this method may be known
3890          * to the system. There are two conditions in which this may occur:
3891          * <ol>
3892          *   <li>The package is on adoptable storage and the device has been removed</li>
3893          *   <li>The package is being removed and the internal structures are partially updated</li>
3894          * </ol>
3895          * The second is an artifact of the current data structures and should be fixed. See
3896          * b/111075456 for one such instance.
3897          * This binder API is cached.  If the algorithm in this method changes,
3898          * or if the underlying objecs (as returned by getSettingLPr()) change
3899          * then the logic that invalidates the cache must be revisited.  See
3900          * calls to invalidateGetPackagesForUidCache() to locate the points at
3901          * which the cache is invalidated.
3902          */
getPackagesForUid(int uid)3903         public final String[] getPackagesForUid(int uid) {
3904             return getPackagesForUidInternal(uid, Binder.getCallingUid());
3905         }
3906 
getPackagesForUidInternal(int uid, int callingUid)3907         private String[] getPackagesForUidInternal(int uid, int callingUid) {
3908             final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
3909             final int userId = UserHandle.getUserId(uid);
3910             final int appId = UserHandle.getAppId(uid);
3911             return getPackagesForUidInternalBody(callingUid, userId, appId, isCallerInstantApp);
3912         }
3913 
getPackagesForUidInternalBody(int callingUid, int userId, int appId, boolean isCallerInstantApp)3914         protected String[] getPackagesForUidInternalBody(int callingUid, int userId, int appId,
3915                                                          boolean isCallerInstantApp) {
3916             // reader
3917             final Object obj = mSettings.getSettingLPr(appId);
3918             if (obj instanceof SharedUserSetting) {
3919                 if (isCallerInstantApp) {
3920                     return null;
3921                 }
3922                 final SharedUserSetting sus = (SharedUserSetting) obj;
3923                 final int N = sus.packages.size();
3924                 String[] res = new String[N];
3925                 int i = 0;
3926                 for (int index = 0; index < N; index++) {
3927                     final PackageSetting ps = sus.packages.valueAt(index);
3928                     if (ps.getInstalled(userId)
3929                             && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
3930                         res[i++] = ps.name;
3931                     }
3932                 }
3933                 return ArrayUtils.trimToSize(res, i);
3934             } else if (obj instanceof PackageSetting) {
3935                 final PackageSetting ps = (PackageSetting) obj;
3936                 if (ps.getInstalled(userId)
3937                         && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
3938                     return new String[]{ps.name};
3939                 }
3940             }
3941             return null;
3942         }
3943 
getProfileParent(int userId)3944         public final UserInfo getProfileParent(int userId) {
3945             final long identity = Binder.clearCallingIdentity();
3946             try {
3947                 return mUserManager.getProfileParent(userId);
3948             } finally {
3949                 Binder.restoreCallingIdentity(identity);
3950             }
3951         }
3952 
3953         /**
3954          * Returns whether or not instant apps have been disabled remotely.
3955          */
areWebInstantAppsDisabled(int userId)3956         private boolean areWebInstantAppsDisabled(int userId) {
3957             return mWebInstantAppsDisabled.get(userId);
3958         }
3959 
3960         /**
3961          * Returns whether or not a full application can see an instant application.
3962          * <p>
3963          * Currently, there are four cases in which this can occur:
3964          * <ol>
3965          * <li>The calling application is a "special" process. Special processes
3966          *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3967          * <li>The calling application has the permission
3968          *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3969          * <li>The calling application is the default launcher on the
3970          *     system partition.</li>
3971          * <li>The calling application is the default app prediction service.</li>
3972          * </ol>
3973          */
canViewInstantApps(int callingUid, int userId)3974         public final boolean canViewInstantApps(int callingUid, int userId) {
3975             if (callingUid < Process.FIRST_APPLICATION_UID) {
3976                 return true;
3977             }
3978             if (mContext.checkCallingOrSelfPermission(
3979                     android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3980                 return true;
3981             }
3982             if (mContext.checkCallingOrSelfPermission(
3983                     android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3984                 final ComponentName homeComponent = getDefaultHomeActivity(userId);
3985                 if (homeComponent != null
3986                         && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3987                     return true;
3988                 }
3989                 // TODO(b/122900055) Change/Remove this and replace with new permission role.
3990                 if (mAppPredictionServicePackage != null
3991                         && isCallerSameApp(mAppPredictionServicePackage, callingUid)) {
3992                     return true;
3993                 }
3994             }
3995             return false;
3996         }
3997 
filterSharedLibPackageLPr(@ullable PackageSetting ps, int uid, int userId, int flags)3998         public final boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid,
3999                 int userId, int flags) {
4000             // Callers can access only the libs they depend on, otherwise they need to explicitly
4001             // ask for the shared libraries given the caller is allowed to access all static libs.
4002             if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4003                 // System/shell/root get to see all static libs
4004                 final int appId = UserHandle.getAppId(uid);
4005                 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4006                         || appId == Process.ROOT_UID) {
4007                     return false;
4008                 }
4009                 // Installer gets to see all static libs.
4010                 if (PackageManager.PERMISSION_GRANTED
4011                         == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
4012                     return false;
4013                 }
4014             }
4015 
4016             // No package means no static lib as it is always on internal storage
4017             if (ps == null || ps.pkg == null || !ps.pkg.isStaticSharedLibrary()) {
4018                 return false;
4019             }
4020 
4021             final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
4022                     ps.pkg.getStaticSharedLibName(), ps.pkg.getStaticSharedLibVersion());
4023             if (libraryInfo == null) {
4024                 return false;
4025             }
4026 
4027             final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4028             final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4029             if (uidPackageNames == null) {
4030                 return true;
4031             }
4032 
4033             for (String uidPackageName : uidPackageNames) {
4034                 if (ps.name.equals(uidPackageName)) {
4035                     return false;
4036                 }
4037                 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4038                 if (uidPs != null) {
4039                     final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4040                             libraryInfo.getName());
4041                     if (index < 0) {
4042                         continue;
4043                     }
4044                     if (uidPs.pkg.getUsesStaticLibrariesVersions()[index]
4045                             == libraryInfo.getLongVersion()) {
4046                         return false;
4047                     }
4048                 }
4049             }
4050             return true;
4051         }
4052 
hasCrossUserPermission( int callingUid, int callingUserId, int userId, boolean requireFullPermission, boolean requirePermissionWhenSameUser)4053         private boolean hasCrossUserPermission(
4054                 int callingUid, int callingUserId, int userId, boolean requireFullPermission,
4055                 boolean requirePermissionWhenSameUser) {
4056             if (!requirePermissionWhenSameUser && userId == callingUserId) {
4057                 return true;
4058             }
4059             if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
4060                 return true;
4061             }
4062             if (requireFullPermission) {
4063                 return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4064             }
4065             return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
4066                     || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
4067         }
4068 
4069         /**
4070          * @param resolveInfos list of resolve infos in descending priority order
4071          * @return if the list contains a resolve info with non-negative priority
4072          */
hasNonNegativePriority(List<ResolveInfo> resolveInfos)4073         private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
4074             return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
4075         }
4076 
hasPermission(String permission)4077         private boolean hasPermission(String permission) {
4078             return mContext.checkCallingOrSelfPermission(permission)
4079                     == PackageManager.PERMISSION_GRANTED;
4080         }
4081 
isCallerSameApp(String packageName, int uid)4082         public final boolean isCallerSameApp(String packageName, int uid) {
4083             AndroidPackage pkg = mPackages.get(packageName);
4084             return pkg != null
4085                     && UserHandle.getAppId(uid) == pkg.getUid();
4086         }
4087 
isComponentVisibleToInstantApp(@ullable ComponentName component)4088         public final boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4089             if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4090                 return true;
4091             }
4092             if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4093                 return true;
4094             }
4095             if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4096                 return true;
4097             }
4098             return false;
4099         }
4100 
isComponentVisibleToInstantApp( @ullable ComponentName component, @ComponentType int type)4101         public final boolean isComponentVisibleToInstantApp(
4102                 @Nullable ComponentName component, @ComponentType int type) {
4103             if (type == TYPE_ACTIVITY) {
4104                 final ParsedActivity activity = mComponentResolver.getActivity(component);
4105                 if (activity == null) {
4106                     return false;
4107                 }
4108                 final boolean visibleToInstantApp =
4109                         (activity.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4110                 final boolean explicitlyVisibleToInstantApp =
4111                         (activity.getFlags() & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP)
4112                         == 0;
4113                 return visibleToInstantApp && explicitlyVisibleToInstantApp;
4114             } else if (type == TYPE_RECEIVER) {
4115                 final ParsedActivity activity = mComponentResolver.getReceiver(component);
4116                 if (activity == null) {
4117                     return false;
4118                 }
4119                 final boolean visibleToInstantApp =
4120                         (activity.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4121                 final boolean explicitlyVisibleToInstantApp =
4122                         (activity.getFlags() & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP)
4123                         == 0;
4124                 return visibleToInstantApp && !explicitlyVisibleToInstantApp;
4125             } else if (type == TYPE_SERVICE) {
4126                 final ParsedService service = mComponentResolver.getService(component);
4127                 return service != null
4128                         && (service.getFlags() & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4129             } else if (type == TYPE_PROVIDER) {
4130                 final ParsedProvider provider = mComponentResolver.getProvider(component);
4131                 return provider != null
4132                         && (provider.getFlags() & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4133             } else if (type == TYPE_UNKNOWN) {
4134                 return isComponentVisibleToInstantApp(component);
4135             }
4136             return false;
4137         }
4138 
4139         /**
4140          * From Android R,
4141          *  camera intents have to match system apps. The only exception to this is if
4142          * the DPC has set the camera persistent preferred activity. This case was introduced
4143          * because it is important that the DPC has the ability to set both system and non-system
4144          * camera persistent preferred activities.
4145          *
4146          * @return {@code true} if the intent is a camera intent and the persistent preferred
4147          * activity was not set by the DPC.
4148          */
isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, String resolvedType, int flags)4149         public final boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
4150                 int userId, String resolvedType, int flags) {
4151             return intent.isImplicitImageCaptureIntent() && !isPersistentPreferredActivitySetByDpm(
4152                     intent, userId, resolvedType, flags);
4153         }
4154 
isInstantApp(String packageName, int userId)4155         public final boolean isInstantApp(String packageName, int userId) {
4156             final int callingUid = Binder.getCallingUid();
4157             enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
4158                     false /* checkShell */, "isInstantApp");
4159 
4160             return isInstantAppInternal(packageName, userId, callingUid);
4161         }
4162 
isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid)4163         public final boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
4164                 int callingUid) {
4165             if (HIDE_EPHEMERAL_APIS) {
4166                 return false;
4167             }
4168             return isInstantAppInternalBody(packageName, userId, callingUid);
4169         }
4170 
isInstantAppInternalBody(String packageName, @UserIdInt int userId, int callingUid)4171         protected boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId,
4172                 int callingUid) {
4173             if (Process.isIsolated(callingUid)) {
4174                 callingUid = getIsolatedOwner(callingUid);
4175             }
4176             final PackageSetting ps = mSettings.getPackageLPr(packageName);
4177             final boolean returnAllowed =
4178                     ps != null
4179                     && (isCallerSameApp(packageName, callingUid)
4180                             || canViewInstantApps(callingUid, userId)
4181                             || mInstantAppRegistry.isInstantAccessGranted(
4182                                     userId, UserHandle.getAppId(callingUid), ps.appId));
4183             if (returnAllowed) {
4184                 return ps.getInstantApp(userId);
4185             }
4186             return false;
4187         }
4188 
isInstantAppResolutionAllowed( Intent intent, List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck, int flags)4189         private boolean isInstantAppResolutionAllowed(
4190                 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
4191                 boolean skipPackageCheck, int flags) {
4192             if (mInstantAppResolverConnection == null) {
4193                 return false;
4194             }
4195             if (instantAppInstallerActivity() == null) {
4196                 return false;
4197             }
4198             if (intent.getComponent() != null) {
4199                 return false;
4200             }
4201             if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
4202                 return false;
4203             }
4204             if (!skipPackageCheck && intent.getPackage() != null) {
4205                 return false;
4206             }
4207             if (!intent.isWebIntent()) {
4208                 // for non web intents, we should not resolve externally if an app already exists to
4209                 // handle it or if the caller didn't explicitly request it.
4210                 if ((resolvedActivities != null && resolvedActivities.size() != 0)
4211                         || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
4212                     return false;
4213                 }
4214             } else {
4215                 if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
4216                     return false;
4217                 } else if (areWebInstantAppsDisabled(userId)) {
4218                     return false;
4219                 }
4220             }
4221             // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4222             // Or if there's already an ephemeral app installed that handles the action
4223             return isInstantAppResolutionAllowedBody(intent, resolvedActivities, userId,
4224                                                        skipPackageCheck, flags);
4225         }
4226 
4227         // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4228         // Or if there's already an ephemeral app installed that handles the action
isInstantAppResolutionAllowedBody( Intent intent, List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck, int flags)4229         protected boolean isInstantAppResolutionAllowedBody(
4230                 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
4231                 boolean skipPackageCheck, int flags) {
4232             final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
4233             for (int n = 0; n < count; n++) {
4234                 final ResolveInfo info = resolvedActivities.get(n);
4235                 final String packageName = info.activityInfo.packageName;
4236                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
4237                 if (ps != null) {
4238                     // only check domain verification status if the app is not a browser
4239                     if (!info.handleAllWebDataURI) {
4240                         if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags,
4241                                 userId)) {
4242                             if (DEBUG_INSTANT) {
4243                                 Slog.v(TAG, "DENY instant app;" + " pkg: " + packageName
4244                                         + ", approved");
4245                             }
4246                             return false;
4247                         }
4248                     }
4249                     if (ps.getInstantApp(userId)) {
4250                         if (DEBUG_INSTANT) {
4251                             Slog.v(TAG, "DENY instant app installed;"
4252                                     + " pkg: " + packageName);
4253                         }
4254                         return false;
4255                     }
4256                 }
4257             }
4258             // We've exhausted all ways to deny ephemeral application; let the system look for them.
4259             return true;
4260         }
4261 
isPersistentPreferredActivitySetByDpm(Intent intent, int userId, String resolvedType, int flags)4262         private boolean isPersistentPreferredActivitySetByDpm(Intent intent, int userId,
4263                 String resolvedType, int flags) {
4264             PersistentPreferredIntentResolver ppir =
4265                     mSettings.getPersistentPreferredActivities(userId);
4266             //TODO(b/158003772): Remove double query
4267             List<PersistentPreferredActivity> pprefs = ppir != null
4268                     ? ppir.queryIntent(intent, resolvedType,
4269                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
4270                     userId)
4271                     : new ArrayList<>();
4272             for (PersistentPreferredActivity ppa : pprefs) {
4273                 if (ppa.mIsSetByDpm) {
4274                     return true;
4275                 }
4276             }
4277             return false;
4278         }
4279 
isRecentsAccessingChildProfiles(int callingUid, int targetUserId)4280         private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
4281             if (!mInjector.getLocalService(ActivityTaskManagerInternal.class)
4282                     .isCallerRecents(callingUid)) {
4283                 return false;
4284             }
4285             final long token = Binder.clearCallingIdentity();
4286             try {
4287                 final int callingUserId = UserHandle.getUserId(callingUid);
4288                 if (ActivityManager.getCurrentUser() != callingUserId) {
4289                     return false;
4290                 }
4291                 return mUserManager.isSameProfileGroup(callingUserId, targetUserId);
4292             } finally {
4293                 Binder.restoreCallingIdentity(token);
4294             }
4295         }
4296 
isSameProfileGroup(@serIdInt int callerUserId, @UserIdInt int userId)4297         public final boolean isSameProfileGroup(@UserIdInt int callerUserId,
4298                 @UserIdInt int userId) {
4299             final long identity = Binder.clearCallingIdentity();
4300             try {
4301                 return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
4302             } finally {
4303                 Binder.restoreCallingIdentity(identity);
4304             }
4305         }
4306 
isUserEnabled(int userId)4307         private boolean isUserEnabled(int userId) {
4308             final long callingId = Binder.clearCallingIdentity();
4309             try {
4310                 UserInfo userInfo = mUserManager.getUserInfo(userId);
4311                 return userInfo != null && userInfo.isEnabled();
4312             } finally {
4313                 Binder.restoreCallingIdentity(callingId);
4314             }
4315         }
4316 
4317         /**
4318          * Returns whether or not access to the application should be filtered.
4319          * <p>
4320          * Access may be limited based upon whether the calling or target applications
4321          * are instant applications.
4322          *
4323          * @see #canViewInstantApps(int, int)
4324          */
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, @Nullable ComponentName component, @ComponentType int componentType, int userId)4325         public final boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps,
4326                 int callingUid,
4327                 @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4328             // if we're in an isolated process, get the real calling UID
4329             if (Process.isIsolated(callingUid)) {
4330                 callingUid = getIsolatedOwner(callingUid);
4331             }
4332             final String instantAppPkgName = getInstantAppPackageName(callingUid);
4333             final boolean callerIsInstantApp = instantAppPkgName != null;
4334             if (ps == null) {
4335                 if (callerIsInstantApp) {
4336                     // pretend the application exists, but, needs to be filtered
4337                     return true;
4338                 }
4339                 return false;
4340             }
4341             // if the target and caller are the same application, don't filter
4342             if (isCallerSameApp(ps.name, callingUid)) {
4343                 return false;
4344             }
4345             if (callerIsInstantApp) {
4346                 // both caller and target are both instant, but, different applications, filter
4347                 if (ps.getInstantApp(userId)) {
4348                     return true;
4349                 }
4350                 // request for a specific component; if it hasn't been explicitly exposed through
4351                 // property or instrumentation target, filter
4352                 if (component != null) {
4353                     final ParsedInstrumentation instrumentation =
4354                             mInstrumentation.get(component);
4355                     if (instrumentation != null
4356                             && isCallerSameApp(instrumentation.getTargetPackage(), callingUid)) {
4357                         return false;
4358                     }
4359                     return !isComponentVisibleToInstantApp(component, componentType);
4360                 }
4361                 // request for application; if no components have been explicitly exposed, filter
4362                 return !ps.pkg.isVisibleToInstantApps();
4363             }
4364             if (ps.getInstantApp(userId)) {
4365                 // caller can see all components of all instant applications, don't filter
4366                 if (canViewInstantApps(callingUid, userId)) {
4367                     return false;
4368                 }
4369                 // request for a specific instant application component, filter
4370                 if (component != null) {
4371                     return true;
4372                 }
4373                 // request for an instant application; if the caller hasn't been granted access,
4374                 //filter
4375                 return !mInstantAppRegistry.isInstantAccessGranted(
4376                         userId, UserHandle.getAppId(callingUid), ps.appId);
4377             }
4378             int appId = UserHandle.getAppId(callingUid);
4379             final SettingBase callingPs = mSettings.getSettingLPr(appId);
4380             return mAppsFilter.shouldFilterApplication(callingUid, callingPs, ps, userId);
4381         }
4382 
4383         /**
4384          * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
4385          */
shouldFilterApplicationLocked( @ullable PackageSetting ps, int callingUid, int userId)4386         public final boolean shouldFilterApplicationLocked(
4387                 @Nullable PackageSetting ps, int callingUid, int userId) {
4388             return shouldFilterApplicationLocked(ps, callingUid, null, TYPE_UNKNOWN, userId);
4389         }
4390 
4391         /**
4392          * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
4393          */
shouldFilterApplicationLocked(@onNull SharedUserSetting sus, int callingUid, int userId)4394         public final boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus,
4395                 int callingUid, int userId) {
4396             boolean filterApp = true;
4397             for (int index = sus.packages.size() - 1; index >= 0 && filterApp; index--) {
4398                 filterApp &= shouldFilterApplicationLocked(sus.packages.valueAt(index),
4399                         callingUid, /* component */ null, TYPE_UNKNOWN, userId);
4400             }
4401             return filterApp;
4402         }
4403 
4404         /**
4405          * Verification statuses are ordered from the worse to the best, except for
4406          * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
4407          */
bestDomainVerificationStatus(int status1, int status2)4408         private int bestDomainVerificationStatus(int status1, int status2) {
4409             if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4410                 return status2;
4411             }
4412             if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4413                 return status1;
4414             }
4415             return (int) MathUtils.max(status1, status2);
4416         }
4417 
4418         // NOTE: Can't remove without a major refactor. Keep around for now.
checkUidPermission(String permName, int uid)4419         public final int checkUidPermission(String permName, int uid) {
4420             return mPermissionManager.checkUidPermission(uid, permName);
4421         }
4422 
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)4423         public int getPackageUidInternal(String packageName, int flags, int userId,
4424                 int callingUid) {
4425             // reader
4426             final AndroidPackage p = mPackages.get(packageName);
4427             if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
4428                 PackageSetting ps = getPackageSettingInternal(p.getPackageName(), callingUid);
4429                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4430                     return -1;
4431                 }
4432                 return UserHandle.getUid(userId, p.getUid());
4433             }
4434             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4435                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
4436                 if (ps != null && ps.isMatch(flags)
4437                         && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
4438                     return UserHandle.getUid(userId, ps.appId);
4439                 }
4440             }
4441 
4442             return -1;
4443         }
4444 
4445         /**
4446          * Update given flags based on encryption status of current user.
4447          */
updateFlags(int flags, int userId)4448         private int updateFlags(int flags, int userId) {
4449             if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4450                     | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4451                 // Caller expressed an explicit opinion about what encryption
4452                 // aware/unaware components they want to see, so fall through and
4453                 // give them what they want
4454             } else {
4455                 final UserManagerInternal umInternal = mInjector.getUserManagerInternal();
4456                 // Caller expressed no opinion, so match based on user state
4457                 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
4458                     flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4459                 } else {
4460                     flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4461                 }
4462             }
4463             return flags;
4464         }
4465 
4466         /**
4467          * Update given flags when being used to request {@link ApplicationInfo}.
4468          */
updateFlagsForApplication(int flags, int userId)4469         public final int updateFlagsForApplication(int flags, int userId) {
4470             return updateFlagsForPackage(flags, userId);
4471         }
4472 
4473         /**
4474          * Update given flags when being used to request {@link ComponentInfo}.
4475          */
updateFlagsForComponent(int flags, int userId)4476         public final int updateFlagsForComponent(int flags, int userId) {
4477             return updateFlags(flags, userId);
4478         }
4479 
4480         /**
4481          * Update given flags when being used to request {@link PackageInfo}.
4482          */
updateFlagsForPackage(int flags, int userId)4483         public final int updateFlagsForPackage(int flags, int userId) {
4484             final boolean isCallerSystemUser = UserHandle.getCallingUserId()
4485                                                == UserHandle.USER_SYSTEM;
4486             if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4487                 // require the permission to be held; the calling uid and given user id referring
4488                 // to the same user is not sufficient
4489                 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4490                         !isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId),
4491                         "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission");
4492             } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0
4493                     && isCallerSystemUser
4494                     && mUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4495                 // If the caller wants all packages and has a restricted profile associated with it,
4496                 // then match all users. This is to make sure that launchers that need to access
4497                 //work
4498                 // profile apps don't start breaking. TODO: Remove this hack when launchers stop
4499                 //using
4500                 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4501                 flags |= PackageManager.MATCH_ANY_USER;
4502             }
4503             return updateFlags(flags, userId);
4504         }
4505 
4506         /**
4507          * Update given flags when being used to request {@link ResolveInfo}.
4508          * <p>Instant apps are resolved specially, depending upon context. Minimally,
4509          * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4510          * flag set. However, this flag is only honoured in three circumstances:
4511          * <ul>
4512          * <li>when called from a system process</li>
4513          * <li>when the caller holds the permission {@code
4514          * android.permission.ACCESS_INSTANT_APPS}</li>
4515          * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4516          * action and a {@code android.intent.category.BROWSABLE} category</li>
4517          * </ul>
4518          */
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc)4519         public final int updateFlagsForResolve(int flags, int userId, int callingUid,
4520                 boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
4521             return updateFlagsForResolve(flags, userId, callingUid,
4522                     wantInstantApps, false /*onlyExposedExplicitly*/,
4523                     isImplicitImageCaptureIntentAndNotSetByDpc);
4524         }
4525 
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc)4526         public final int updateFlagsForResolve(int flags, int userId, int callingUid,
4527                 boolean wantInstantApps, boolean onlyExposedExplicitly,
4528                 boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
4529             // Safe mode means we shouldn't match any third-party components
4530             if (safeMode() || isImplicitImageCaptureIntentAndNotSetByDpc) {
4531                 flags |= PackageManager.MATCH_SYSTEM_ONLY;
4532             }
4533             if (getInstantAppPackageName(callingUid) != null) {
4534                 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4535                 if (onlyExposedExplicitly) {
4536                     flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4537                 }
4538                 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4539                 flags |= PackageManager.MATCH_INSTANT;
4540             } else {
4541                 final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4542                 final boolean allowMatchInstant = wantInstantApps
4543                         || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4544                 flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4545                         | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4546                 if (!allowMatchInstant) {
4547                     flags &= ~PackageManager.MATCH_INSTANT;
4548                 }
4549             }
4550             return updateFlagsForComponent(flags, userId);
4551         }
4552 
4553         /**
4554          * Checks if the request is from the system or an app that has the appropriate cross-user
4555          * permissions defined as follows:
4556          * <ul>
4557          * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
4558          * <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group
4559          * to the caller.</li>
4560          * <li>Otherwise,
4561          *  INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile
4562          * group as the caller.</li>
4563          * </ul>
4564          *
4565          * @param checkShell whether to prevent shell from access if there's a debugging restriction
4566          * @param message the message to log on security exception
4567          */
enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)4568         public final void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
4569                 boolean requireFullPermission, boolean checkShell, String message) {
4570             if (userId < 0) {
4571                 throw new IllegalArgumentException("Invalid userId " + userId);
4572             }
4573             if (checkShell) {
4574                 PackageManagerServiceUtils.enforceShellRestriction(
4575                         mInjector.getUserManagerInternal(),
4576                         UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4577             }
4578             final int callingUserId = UserHandle.getUserId(callingUid);
4579             if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
4580                     /*requirePermissionWhenSameUser= */ false)) {
4581                 return;
4582             }
4583             final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
4584             if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
4585                     mContext,
4586                     android.Manifest.permission.INTERACT_ACROSS_PROFILES,
4587                     PermissionChecker.PID_UNKNOWN,
4588                     callingUid,
4589                     getPackage(callingUid).getPackageName())
4590                     == PermissionChecker.PERMISSION_GRANTED) {
4591                 return;
4592             }
4593             String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
4594                     callingUid, userId, message, requireFullPermission, isSameProfileGroup);
4595             Slog.w(TAG, errorMessage);
4596             throw new SecurityException(errorMessage);
4597         }
4598 
4599         /**
4600          * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
4601          * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
4602          *
4603          * @param checkShell whether to prevent shell from access if there's a debugging restriction
4604          * @param message the message to log on security exception
4605          */
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)4606         public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
4607                 boolean requireFullPermission, boolean checkShell, String message) {
4608             enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, false,
4609                     message);
4610         }
4611 
4612         /**
4613          * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
4614          * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
4615          *
4616          * @param checkShell whether to prevent shell from access if there's a debugging restriction
4617          * @param requirePermissionWhenSameUser When {@code true}, still require the cross user
4618          *                                      permission to be held even if the callingUid and
4619          * userId
4620          *                                      reference the same user.
4621          * @param message the message to log on security exception
4622          */
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)4623         public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
4624                 boolean requireFullPermission, boolean checkShell,
4625                 boolean requirePermissionWhenSameUser, String message) {
4626             if (userId < 0) {
4627                 throw new IllegalArgumentException("Invalid userId " + userId);
4628             }
4629             if (checkShell) {
4630                 PackageManagerServiceUtils.enforceShellRestriction(
4631                         mInjector.getUserManagerInternal(),
4632                         UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4633             }
4634             final int callingUserId = UserHandle.getUserId(callingUid);
4635             if (hasCrossUserPermission(
4636                     callingUid, callingUserId, userId, requireFullPermission,
4637                     requirePermissionWhenSameUser)) {
4638                 return;
4639             }
4640             String errorMessage = buildInvalidCrossUserPermissionMessage(
4641                     callingUid, userId, message, requireFullPermission);
4642             Slog.w(TAG, errorMessage);
4643             throw new SecurityException(errorMessage);
4644         }
4645 
getSigningDetails(@onNull String packageName)4646         public SigningDetails getSigningDetails(@NonNull String packageName) {
4647             AndroidPackage p = mPackages.get(packageName);
4648             if (p == null) {
4649                 return null;
4650             }
4651             return p.getSigningDetails();
4652         }
4653 
getSigningDetails(int uid)4654         public SigningDetails getSigningDetails(int uid) {
4655             final int appId = UserHandle.getAppId(uid);
4656             final Object obj = mSettings.getSettingLPr(appId);
4657             if (obj != null) {
4658                 if (obj instanceof SharedUserSetting) {
4659                     return ((SharedUserSetting) obj).signatures.mSigningDetails;
4660                 } else if (obj instanceof PackageSetting) {
4661                     final PackageSetting ps = (PackageSetting) obj;
4662                     return ps.signatures.mSigningDetails;
4663                 }
4664             }
4665             return SigningDetails.UNKNOWN;
4666         }
4667 
filterAppAccess(AndroidPackage pkg, int callingUid, int userId)4668         public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
4669             PackageSetting ps = getPackageSetting(pkg.getPackageName());
4670             return shouldFilterApplicationLocked(ps, callingUid,
4671                     userId);
4672         }
4673 
filterAppAccess(String packageName, int callingUid, int userId)4674         public boolean filterAppAccess(String packageName, int callingUid, int userId) {
4675             PackageSetting ps = getPackageSetting(packageName);
4676             return shouldFilterApplicationLocked(ps, callingUid,
4677                     userId);
4678         }
4679 
dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState)4680         public void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
4681             final String packageName = dumpState.getTargetPackageName();
4682             final boolean checkin = dumpState.isCheckIn();
4683 
4684             switch (type) {
4685                 case DumpState.DUMP_VERSION:
4686                 {
4687                     if (dumpState.onTitlePrinted()) {
4688                         pw.println();
4689                     }
4690                     pw.println("Database versions:");
4691                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
4692                     break;
4693                 }
4694 
4695                 case DumpState.DUMP_LIBS:
4696                 {
4697                     boolean printedHeader = false;
4698                     final int numSharedLibraries = mSharedLibraries.size();
4699                     for (int index = 0; index < numSharedLibraries; index++) {
4700                         final String libName = mSharedLibraries.keyAt(index);
4701                         final WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
4702                                 mSharedLibraries.get(libName);
4703                         if (versionedLib == null) {
4704                             continue;
4705                         }
4706                         final int versionCount = versionedLib.size();
4707                         for (int i = 0; i < versionCount; i++) {
4708                             SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
4709                             if (!checkin) {
4710                                 if (!printedHeader) {
4711                                     if (dumpState.onTitlePrinted()) {
4712                                         pw.println();
4713                                     }
4714                                     pw.println("Libraries:");
4715                                     printedHeader = true;
4716                                 }
4717                                 pw.print("  ");
4718                             } else {
4719                                 pw.print("lib,");
4720                             }
4721                             pw.print(libraryInfo.getName());
4722                             if (libraryInfo.isStatic()) {
4723                                 pw.print(" version=" + libraryInfo.getLongVersion());
4724                             }
4725                             if (!checkin) {
4726                                 pw.print(" -> ");
4727                             }
4728                             if (libraryInfo.getPath() != null) {
4729                                 if (libraryInfo.isNative()) {
4730                                     pw.print(" (so) ");
4731                                 } else {
4732                                     pw.print(" (jar) ");
4733                                 }
4734                                 pw.print(libraryInfo.getPath());
4735                             } else {
4736                                 pw.print(" (apk) ");
4737                                 pw.print(libraryInfo.getPackageName());
4738                             }
4739                             pw.println();
4740                         }
4741                     }
4742                     break;
4743                 }
4744 
4745                 case DumpState.DUMP_PREFERRED:
4746                     mSettings.dumpPreferred(pw, dumpState, packageName);
4747                     break;
4748 
4749                 case DumpState.DUMP_PREFERRED_XML:
4750                 {
4751                     pw.flush();
4752                     FileOutputStream fout = new FileOutputStream(fd);
4753                     BufferedOutputStream str = new BufferedOutputStream(fout);
4754                     TypedXmlSerializer serializer = Xml.newFastSerializer();
4755                     try {
4756                         serializer.setOutput(str, StandardCharsets.UTF_8.name());
4757                         serializer.startDocument(null, true);
4758                         serializer.setFeature(
4759                                 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
4760                         mSettings.writePreferredActivitiesLPr(serializer, 0,
4761                                 dumpState.isFullPreferred());
4762                         serializer.endDocument();
4763                         serializer.flush();
4764                     } catch (IllegalArgumentException e) {
4765                         pw.println("Failed writing: " + e);
4766                     } catch (IllegalStateException e) {
4767                         pw.println("Failed writing: " + e);
4768                     } catch (IOException e) {
4769                         pw.println("Failed writing: " + e);
4770                     }
4771                     break;
4772                 }
4773 
4774                 case DumpState.DUMP_QUERIES:
4775                 {
4776                     final PackageSetting setting = mSettings.getPackageLPr(packageName);
4777                     Integer filteringAppId = setting == null ? null : setting.appId;
4778                     mAppsFilter.dumpQueries(
4779                             pw, filteringAppId, dumpState, mUserManager.getUserIds(),
4780                             this::getPackagesForUidInternalBody);
4781                     break;
4782                 }
4783 
4784                 case DumpState.DUMP_DOMAIN_PREFERRED:
4785                 {
4786                     final android.util.IndentingPrintWriter writer =
4787                             new android.util.IndentingPrintWriter(pw);
4788                     if (dumpState.onTitlePrinted()) pw.println();
4789 
4790                     writer.println("Domain verification status:");
4791                     writer.increaseIndent();
4792                     try {
4793                         mDomainVerificationManager.printState(writer, packageName,
4794                                 UserHandle.USER_ALL, mSettings::getPackageLPr);
4795                     } catch (Exception e) {
4796                         pw.println("Failure printing domain verification information");
4797                         Slog.e(TAG, "Failure printing domain verification information", e);
4798                     }
4799                     writer.decreaseIndent();
4800                     break;
4801                 }
4802 
4803                 case DumpState.DUMP_DEXOPT:
4804                 {
4805                     final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
4806                     ipw.println();
4807                     ipw.println("Dexopt state:");
4808                     ipw.increaseIndent();
4809                     Collection<PackageSetting> pkgSettings;
4810                     if (packageName != null) {
4811                         PackageSetting targetPkgSetting = mSettings.getPackageLPr(packageName);
4812                         if (targetPkgSetting != null) {
4813                             pkgSettings = Collections.singletonList(targetPkgSetting);
4814                         } else {
4815                             ipw.println("Unable to find package: " + packageName);
4816                             return;
4817                         }
4818                     } else {
4819                         pkgSettings = mSettings.getPackagesLocked().values();
4820                     }
4821 
4822                     for (PackageSetting pkgSetting : pkgSettings) {
4823                         final AndroidPackage pkg = pkgSetting.getPkg();
4824                         if (pkg == null) {
4825                             continue;
4826                         }
4827                         ipw.println("[" + pkgSetting.name + "]");
4828                         ipw.increaseIndent();
4829                         mPackageDexOptimizer.dumpDexoptState(ipw, pkg, pkgSetting,
4830                                 mDexManager.getPackageUseInfoOrDefault(pkg.getPackageName()));
4831                         ipw.decreaseIndent();
4832                     }
4833                     break;
4834                 }
4835 
4836                 case DumpState.DUMP_COMPILER_STATS:
4837                 {
4838                     final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
4839                     ipw.println();
4840                     ipw.println("Compiler stats:");
4841                     ipw.increaseIndent();
4842                     Collection<AndroidPackage> packages;
4843                     if (packageName != null) {
4844                         AndroidPackage targetPackage = mPackages.get(packageName);
4845                         if (targetPackage != null) {
4846                             packages = Collections.singletonList(targetPackage);
4847                         } else {
4848                             ipw.println("Unable to find package: " + packageName);
4849                             return;
4850                         }
4851                     } else {
4852                         packages = mPackages.values();
4853                     }
4854 
4855                     for (AndroidPackage pkg : packages) {
4856                         final String pkgName = pkg.getPackageName();
4857                         ipw.println("[" + pkgName + "]");
4858                         ipw.increaseIndent();
4859 
4860                         CompilerStats.PackageStats stats = mCompilerStats.getPackageStats(pkgName);
4861                         if (stats == null) {
4862                             ipw.println("(No recorded stats)");
4863                         } else {
4864                             stats.dump(ipw);
4865                         }
4866                         ipw.decreaseIndent();
4867                     }
4868                     break;
4869                 }
4870             } // switch
4871         }
4872 
4873         // The body of findPreferredActivity.
findPreferredActivityBody( Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered, int callingUid, boolean isDeviceProvisioned)4874         protected FindPreferredActivityBodyResult findPreferredActivityBody(
4875                 Intent intent, String resolvedType, int flags,
4876                 List<ResolveInfo> query, boolean always,
4877                 boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered,
4878                 int callingUid, boolean isDeviceProvisioned) {
4879             FindPreferredActivityBodyResult result = new FindPreferredActivityBodyResult();
4880 
4881             flags = updateFlagsForResolve(
4882                     flags, userId, callingUid, false /*includeInstantApps*/,
4883                     isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
4884                             resolvedType, flags));
4885             intent = updateIntentForResolve(intent);
4886 
4887             // Try to find a matching persistent preferred activity.
4888             result.mPreferredResolveInfo = findPersistentPreferredActivityLP(intent,
4889                     resolvedType, flags, query, debug, userId);
4890 
4891             // If a persistent preferred activity matched, use it.
4892             if (result.mPreferredResolveInfo != null) {
4893                 return result;
4894             }
4895 
4896             PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
4897             // Get the list of preferred activities that handle the intent
4898             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
4899             List<PreferredActivity> prefs = pir != null
4900                     ? pir.queryIntent(intent, resolvedType,
4901                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
4902                             userId)
4903                     : null;
4904             if (prefs != null && prefs.size() > 0) {
4905 
4906                 // First figure out how good the original match set is.
4907                 // We will only allow preferred activities that came
4908                 // from the same match quality.
4909                 int match = 0;
4910 
4911                 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
4912 
4913                 final int N = query.size();
4914                 for (int j = 0; j < N; j++) {
4915                     final ResolveInfo ri = query.get(j);
4916                     if (DEBUG_PREFERRED || debug) {
4917                         Slog.v(TAG, "Match for " + ri.activityInfo
4918                                 + ": 0x" + Integer.toHexString(match));
4919                     }
4920                     if (ri.match > match) {
4921                         match = ri.match;
4922                     }
4923                 }
4924 
4925                 if (DEBUG_PREFERRED || debug) {
4926                     Slog.v(TAG, "Best match: 0x" + Integer.toHexString(match));
4927                 }
4928                 match &= IntentFilter.MATCH_CATEGORY_MASK;
4929                 final int M = prefs.size();
4930                 for (int i = 0; i < M; i++) {
4931                     final PreferredActivity pa = prefs.get(i);
4932                     if (DEBUG_PREFERRED || debug) {
4933                         Slog.v(TAG, "Checking PreferredActivity ds="
4934                                 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
4935                                 + "\n  component=" + pa.mPref.mComponent);
4936                         pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4937                     }
4938                     if (pa.mPref.mMatch != match) {
4939                         if (DEBUG_PREFERRED || debug) {
4940                             Slog.v(TAG, "Skipping bad match "
4941                                     + Integer.toHexString(pa.mPref.mMatch));
4942                         }
4943                         continue;
4944                     }
4945                     // If it's not an "always" type preferred activity and that's what we're
4946                     // looking for, skip it.
4947                     if (always && !pa.mPref.mAlways) {
4948                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
4949                         continue;
4950                     }
4951                     final ActivityInfo ai = getActivityInfo(
4952                             pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
4953                                     | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
4954                             userId);
4955                     if (DEBUG_PREFERRED || debug) {
4956                         Slog.v(TAG, "Found preferred activity:");
4957                         if (ai != null) {
4958                             ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4959                         } else {
4960                             Slog.v(TAG, "  null");
4961                         }
4962                     }
4963                     final boolean excludeSetupWizardHomeActivity = isHomeIntent(intent)
4964                             && !isDeviceProvisioned;
4965                     final boolean allowSetMutation = !excludeSetupWizardHomeActivity
4966                             && !queryMayBeFiltered;
4967                     if (ai == null) {
4968                         // Do not remove launcher's preferred activity during SetupWizard
4969                         // due to it may not install yet
4970                         if (!allowSetMutation) {
4971                             continue;
4972                         }
4973 
4974                         // This previously registered preferred activity
4975                         // component is no longer known.  Most likely an update
4976                         // to the app was installed and in the new version this
4977                         // component no longer exists.  Clean it up by removing
4978                         // it from the preferred activities list, and skip it.
4979                         Slog.w(TAG, "Removing dangling preferred activity: "
4980                                 + pa.mPref.mComponent);
4981                         pir.removeFilter(pa);
4982                         result.mChanged = true;
4983                         continue;
4984                     }
4985                     for (int j = 0; j < N; j++) {
4986                         final ResolveInfo ri = query.get(j);
4987                         if (!ri.activityInfo.applicationInfo.packageName
4988                                 .equals(ai.applicationInfo.packageName)) {
4989                             continue;
4990                         }
4991                         if (!ri.activityInfo.name.equals(ai.name)) {
4992                             continue;
4993                         }
4994 
4995                         if (removeMatches && allowSetMutation) {
4996                             pir.removeFilter(pa);
4997                             result.mChanged = true;
4998                             if (DEBUG_PREFERRED) {
4999                                 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
5000                             }
5001                             break;
5002                         }
5003 
5004                         // Okay we found a previously set preferred or last chosen app.
5005                         // If the result set is different from when this
5006                         // was created, and is not a subset of the preferred set, we need to
5007                         // clear it and re-ask the user their preference, if we're looking for
5008                         // an "always" type entry.
5009 
5010                         if (always && !pa.mPref.sameSet(query, excludeSetupWizardHomeActivity)) {
5011                             if (pa.mPref.isSuperset(query, excludeSetupWizardHomeActivity)) {
5012                                 if (allowSetMutation) {
5013                                     // some components of the set are no longer present in
5014                                     // the query, but the preferred activity can still be reused
5015                                     if (DEBUG_PREFERRED) {
5016                                         Slog.i(TAG, "Result set changed, but PreferredActivity"
5017                                                 + " is still valid as only non-preferred"
5018                                                 + " components were removed for " + intent
5019                                                 + " type " + resolvedType);
5020                                     }
5021                                     // remove obsolete components and re-add the up-to-date
5022                                     // filter
5023                                     PreferredActivity freshPa = new PreferredActivity(pa,
5024                                             pa.mPref.mMatch,
5025                                             pa.mPref.discardObsoleteComponents(query),
5026                                             pa.mPref.mComponent,
5027                                             pa.mPref.mAlways);
5028                                     pir.removeFilter(pa);
5029                                     pir.addFilter(freshPa);
5030                                     result.mChanged = true;
5031                                 } else {
5032                                     if (DEBUG_PREFERRED) {
5033                                         Slog.i(TAG, "Do not remove preferred activity");
5034                                     }
5035                                 }
5036                             } else {
5037                                 if (allowSetMutation) {
5038                                     Slog.i(TAG,
5039                                             "Result set changed, dropping preferred activity "
5040                                                     + "for " + intent + " type "
5041                                                     + resolvedType);
5042                                     if (DEBUG_PREFERRED) {
5043                                         Slog.v(TAG,
5044                                                 "Removing preferred activity since set changed "
5045                                                         + pa.mPref.mComponent);
5046                                     }
5047                                     pir.removeFilter(pa);
5048                                     // Re-add the filter as a "last chosen" entry (!always)
5049                                     PreferredActivity lastChosen = new PreferredActivity(
5050                                             pa, pa.mPref.mMatch, null, pa.mPref.mComponent,
5051                                             false);
5052                                     pir.addFilter(lastChosen);
5053                                     result.mChanged = true;
5054                                 }
5055                                 result.mPreferredResolveInfo = null;
5056                                 return result;
5057                             }
5058                         }
5059 
5060                         // Yay! Either the set matched or we're looking for the last chosen
5061                         if (DEBUG_PREFERRED || debug) {
5062                             Slog.v(TAG, "Returning preferred activity: "
5063                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5064                         }
5065                         result.mPreferredResolveInfo = ri;
5066                         return result;
5067                     }
5068                 }
5069             }
5070             return result;
5071         }
5072 
findPreferredActivityInternal( Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered)5073         public final FindPreferredActivityBodyResult findPreferredActivityInternal(
5074                 Intent intent, String resolvedType, int flags,
5075                 List<ResolveInfo> query, boolean always,
5076                 boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
5077 
5078             final int callingUid = Binder.getCallingUid();
5079             // Do NOT hold the packages lock; this calls up into the settings provider which
5080             // could cause a deadlock.
5081             final boolean isDeviceProvisioned =
5082                     android.provider.Settings.Global.getInt(mContext.getContentResolver(),
5083                             android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
5084             // Find the preferred activity - the lock is held inside the method.
5085             return findPreferredActivityBody(
5086                     intent, resolvedType, flags, query, always, removeMatches, debug,
5087                     userId, queryMayBeFiltered, callingUid, isDeviceProvisioned);
5088         }
5089 
findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)5090         public final ResolveInfo findPersistentPreferredActivityLP(Intent intent,
5091                 String resolvedType,
5092                 int flags, List<ResolveInfo> query, boolean debug, int userId) {
5093             final int N = query.size();
5094             PersistentPreferredIntentResolver ppir =
5095                     mSettings.getPersistentPreferredActivities(userId);
5096             // Get the list of persistent preferred activities that handle the intent
5097             if (DEBUG_PREFERRED || debug) {
5098                 Slog.v(TAG, "Looking for persistent preferred activities...");
5099             }
5100             List<PersistentPreferredActivity> pprefs = ppir != null
5101                     ? ppir.queryIntent(intent, resolvedType,
5102                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5103                             userId)
5104                     : null;
5105             if (pprefs != null && pprefs.size() > 0) {
5106                 final int M = pprefs.size();
5107                 for (int i = 0; i < M; i++) {
5108                     final PersistentPreferredActivity ppa = pprefs.get(i);
5109                     if (DEBUG_PREFERRED || debug) {
5110                         Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5111                                 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5112                                 + "\n  component=" + ppa.mComponent);
5113                         ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5114                     }
5115                     final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5116                             flags | MATCH_DISABLED_COMPONENTS, userId);
5117                     if (DEBUG_PREFERRED || debug) {
5118                         Slog.v(TAG, "Found persistent preferred activity:");
5119                         if (ai != null) {
5120                             ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5121                         } else {
5122                             Slog.v(TAG, "  null");
5123                         }
5124                     }
5125                     if (ai == null) {
5126                         // This previously registered persistent preferred activity
5127                         // component is no longer known. Ignore it and do NOT remove it.
5128                         continue;
5129                     }
5130                     for (int j = 0; j < N; j++) {
5131                         final ResolveInfo ri = query.get(j);
5132                         if (!ri.activityInfo.applicationInfo.packageName
5133                                 .equals(ai.applicationInfo.packageName)) {
5134                             continue;
5135                         }
5136                         if (!ri.activityInfo.name.equals(ai.name)) {
5137                             continue;
5138                         }
5139                         //  Found a persistent preference that can handle the intent.
5140                         if (DEBUG_PREFERRED || debug) {
5141                             Slog.v(TAG, "Returning persistent preferred activity: "
5142                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5143                         }
5144                         return ri;
5145                     }
5146                 }
5147             }
5148             return null;
5149         }
5150     }
5151 
5152     /**
5153      * This subclass is the external interface to the live computer.  Some internal helper
5154      * methods are overridden to fetch live data instead of snapshot data.  For each
5155      * Computer interface that is overridden in this class, the override takes the PM lock
5156      * and then delegates to the live computer engine.  This is required because there are
5157      * no locks taken in the engine itself.
5158      */
5159     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
5160     protected static class ComputerLocked extends ComputerEngine {
5161         private final Object mLock;
5162 
ComputerLocked(Snapshot args)5163         ComputerLocked(Snapshot args) {
5164             super(args);
5165             mLock = mService.mLock;
5166         }
5167 
resolveComponentName()5168         protected final ComponentName resolveComponentName() {
5169             return mService.mResolveComponentName;
5170         }
instantAppInstallerActivity()5171         protected final ActivityInfo instantAppInstallerActivity() {
5172             return mService.mInstantAppInstallerActivity;
5173         }
androidApplication()5174         protected final ApplicationInfo androidApplication() {
5175             return mService.mAndroidApplication;
5176         }
5177 
queryIntentServicesInternalBody(Intent intent, String resolvedType, int flags, int userId, int callingUid, String instantAppPkgName)5178         public final @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent,
5179                 String resolvedType, int flags, int userId, int callingUid,
5180                 String instantAppPkgName) {
5181             synchronized (mLock) {
5182                 return super.queryIntentServicesInternalBody(intent, resolvedType, flags, userId,
5183                         callingUid, instantAppPkgName);
5184             }
5185         }
queryIntentActivitiesInternalBody( Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)5186         public final @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
5187                 Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
5188                 boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
5189                 String instantAppPkgName) {
5190             synchronized (mLock) {
5191                 return super.queryIntentActivitiesInternalBody(intent, resolvedType, flags,
5192                         filterCallingUid, userId, resolveForStart, allowDynamicSplits, pkgName,
5193                         instantAppPkgName);
5194             }
5195         }
getActivityInfoInternalBody(ComponentName component, int flags, int filterCallingUid, int userId)5196         public final ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags,
5197                 int filterCallingUid, int userId) {
5198             synchronized (mLock) {
5199                 return super.getActivityInfoInternalBody(component, flags, filterCallingUid,
5200                         userId);
5201             }
5202         }
getPackage(String packageName)5203         public final AndroidPackage getPackage(String packageName) {
5204             synchronized (mLock) {
5205                 return super.getPackage(packageName);
5206             }
5207         }
getPackage(int uid)5208         public final AndroidPackage getPackage(int uid) {
5209             synchronized (mLock) {
5210                 return super.getPackage(uid);
5211             }
5212         }
getApplicationInfoInternalBody(String packageName, int flags, int filterCallingUid, int userId)5213         public final ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags,
5214                 int filterCallingUid, int userId) {
5215             synchronized (mLock) {
5216                 return super.getApplicationInfoInternalBody(packageName, flags, filterCallingUid,
5217                         userId);
5218             }
5219         }
filterCandidatesWithDomainPreferredActivitiesLPrBody( Intent intent, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug)5220         public final ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody(
5221                 Intent intent, int matchFlags, List<ResolveInfo> candidates,
5222                 CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug) {
5223             synchronized (mLock) {
5224                 return super.filterCandidatesWithDomainPreferredActivitiesLPrBody(intent,
5225                         matchFlags, candidates, xpDomainInfo, userId, debug);
5226             }
5227         }
getPackageInfoInternalBody(String packageName, long versionCode, int flags, int filterCallingUid, int userId)5228         public final PackageInfo getPackageInfoInternalBody(String packageName, long versionCode,
5229                 int flags, int filterCallingUid, int userId) {
5230             synchronized (mLock) {
5231                 return super.getPackageInfoInternalBody(packageName, versionCode, flags,
5232                         filterCallingUid, userId);
5233             }
5234         }
getPackageSettingInternal(String packageName, int callingUid)5235         public final PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
5236             synchronized (mLock) {
5237                 return super.getPackageSettingInternal(packageName, callingUid);
5238             }
5239         }
getInstalledPackagesBody(int flags, int userId, int callingUid)5240         public final ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
5241                 int callingUid) {
5242             synchronized (mLock) {
5243                 return super.getInstalledPackagesBody(flags, userId, callingUid);
5244             }
5245         }
getServiceInfoBody(ComponentName component, int flags, int userId, int callingUid)5246         public final ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId,
5247                 int callingUid) {
5248             synchronized (mLock) {
5249                 return super.getServiceInfoBody(component, flags, userId, callingUid);
5250             }
5251         }
getInstantAppPackageName(int callingUid)5252         public final String getInstantAppPackageName(int callingUid) {
5253             synchronized (mLock) {
5254                 return super.getInstantAppPackageName(callingUid);
5255             }
5256         }
getPackagesForUidInternalBody(int callingUid, int userId, int appId, boolean isCallerInstantApp)5257         public final String[] getPackagesForUidInternalBody(int callingUid, int userId, int appId,
5258                 boolean isCallerInstantApp) {
5259             synchronized (mLock) {
5260                 return super.getPackagesForUidInternalBody(callingUid, userId, appId,
5261                         isCallerInstantApp);
5262             }
5263         }
isInstantAppInternalBody(String packageName, @UserIdInt int userId, int callingUid)5264         public final boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId,
5265                 int callingUid) {
5266             synchronized (mLock) {
5267                 return super.isInstantAppInternalBody(packageName, userId, callingUid);
5268             }
5269         }
isInstantAppResolutionAllowedBody(Intent intent, List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck, int flags)5270         public final boolean isInstantAppResolutionAllowedBody(Intent intent,
5271                 List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck,
5272                 int flags) {
5273             synchronized (mLock) {
5274                 return super.isInstantAppResolutionAllowedBody(intent, resolvedActivities, userId,
5275                         skipPackageCheck, flags);
5276             }
5277         }
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)5278         public final int getPackageUidInternal(String packageName, int flags, int userId,
5279                 int callingUid) {
5280             synchronized (mLock) {
5281                 return super.getPackageUidInternal(packageName, flags, userId, callingUid);
5282             }
5283         }
getSigningDetails(@onNull String packageName)5284         public final SigningDetails getSigningDetails(@NonNull String packageName) {
5285             synchronized (mLock) {
5286                 return super.getSigningDetails(packageName);
5287             }
5288         }
getSigningDetails(int uid)5289         public final SigningDetails getSigningDetails(int uid) {
5290             synchronized (mLock) {
5291                 return super.getSigningDetails(uid);
5292             }
5293         }
filterAppAccess(AndroidPackage pkg, int callingUid, int userId)5294         public final boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
5295             synchronized (mLock) {
5296                 return super.filterAppAccess(pkg, callingUid, userId);
5297             }
5298         }
filterAppAccess(String packageName, int callingUid, int userId)5299         public final boolean filterAppAccess(String packageName, int callingUid, int userId) {
5300             synchronized (mLock) {
5301                 return super.filterAppAccess(packageName, callingUid, userId);
5302             }
5303         }
dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState)5304         public final void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
5305             synchronized (mLock) {
5306                 super.dump(type, fd, pw, dumpState);
5307             }
5308         }
findPreferredActivityBody(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered, int callingUid, boolean isDeviceProvisioned)5309         public final FindPreferredActivityBodyResult findPreferredActivityBody(Intent intent,
5310                 String resolvedType, int flags, List<ResolveInfo> query, boolean always,
5311                 boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered,
5312                 int callingUid, boolean isDeviceProvisioned) {
5313             synchronized (mLock) {
5314                 return super.findPreferredActivityBody(intent, resolvedType, flags, query, always,
5315                         removeMatches, debug, userId, queryMayBeFiltered, callingUid,
5316                         isDeviceProvisioned);
5317             }
5318         }
5319     }
5320 
5321     /**
5322      * This subclass delegates to methods in a Computer after reference-counting the computer.
5323      */
5324     private static class ComputerTracker implements Computer {
5325 
5326         // The number of times a thread reused a computer in its stack instead of fetching
5327         // a snapshot computer.
5328         private final AtomicInteger mReusedSnapshot = new AtomicInteger(0);
5329 
5330         // The number of times a thread reused a computer in its stack instead of fetching
5331         // a live computer.
5332         private final AtomicInteger mReusedLive = new AtomicInteger(0);
5333 
5334         private PackageManagerService mService;
ComputerTracker(PackageManagerService s)5335         ComputerTracker(PackageManagerService s) {
5336             mService = s;
5337         }
5338 
live()5339         private ThreadComputer live() {
5340             ThreadComputer current = mService.sThreadComputer.get();
5341             if (current.mRefCount > 0) {
5342                 current.acquire();
5343                 mReusedLive.incrementAndGet();
5344             } else {
5345                 current.acquire(mService.liveComputer());
5346             }
5347             return current;
5348         }
5349 
snapshot()5350         private ThreadComputer snapshot() {
5351             ThreadComputer current = mService.sThreadComputer.get();
5352             if (current.mRefCount > 0) {
5353                 current.acquire();
5354                 mReusedSnapshot.incrementAndGet();
5355             } else {
5356                 current.acquire(mService.snapshotComputer());
5357             }
5358             return current;
5359         }
5360 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits)5361         public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5362                 String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
5363                 int filterCallingUid, int userId, boolean resolveForStart,
5364                 boolean allowDynamicSplits) {
5365             ThreadComputer current = snapshot();
5366             try {
5367                 return current.mComputer.queryIntentActivitiesInternal(intent, resolvedType, flags,
5368                         privateResolveFlags, filterCallingUid, userId, resolveForStart,
5369                         allowDynamicSplits);
5370             } finally {
5371                 current.release();
5372             }
5373         }
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId)5374         public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5375                 String resolvedType, int flags, int userId) {
5376             ThreadComputer current = snapshot();
5377             try {
5378                 return current.mComputer.queryIntentActivitiesInternal(intent, resolvedType, flags,
5379                         userId);
5380             } finally {
5381                 current.release();
5382             }
5383         }
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps)5384         public final @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
5385                 String resolvedType, int flags, int userId, int callingUid,
5386                 boolean includeInstantApps) {
5387             ThreadComputer current = snapshot();
5388             try {
5389                 return current.mComputer.queryIntentServicesInternal(intent, resolvedType, flags,
5390                         userId, callingUid, includeInstantApps);
5391             } finally {
5392                 current.release();
5393             }
5394         }
queryIntentActivitiesInternalBody( Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)5395         public final @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
5396                 Intent intent,
5397                 String resolvedType, int flags, int filterCallingUid, int userId,
5398                 boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
5399                 String instantAppPkgName) {
5400             ThreadComputer current = live();
5401             try {
5402                 return current.mComputer.queryIntentActivitiesInternalBody(intent, resolvedType,
5403                         flags, filterCallingUid, userId, resolveForStart, allowDynamicSplits,
5404                         pkgName, instantAppPkgName);
5405             } finally {
5406                 current.release();
5407             }
5408         }
getActivityInfo(ComponentName component, int flags, int userId)5409         public final ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
5410             ThreadComputer current = snapshot();
5411             try {
5412                 return current.mComputer.getActivityInfo(component, flags, userId);
5413             } finally {
5414                 current.release();
5415             }
5416         }
getActivityInfoInternal(ComponentName component, int flags, int filterCallingUid, int userId)5417         public final ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
5418                 int filterCallingUid, int userId) {
5419             ThreadComputer current = live();
5420             try {
5421                 return current.mComputer.getActivityInfoInternal(component, flags, filterCallingUid,
5422                         userId);
5423             } finally {
5424                 current.release();
5425             }
5426         }
getPackage(String packageName)5427         public final AndroidPackage getPackage(String packageName) {
5428             ThreadComputer current = snapshot();
5429             try {
5430                 return current.mComputer.getPackage(packageName);
5431             } finally {
5432                 current.release();
5433             }
5434         }
getPackage(int uid)5435         public final AndroidPackage getPackage(int uid) {
5436             ThreadComputer current = snapshot();
5437             try {
5438                 return current.mComputer.getPackage(uid);
5439             } finally {
5440                 current.release();
5441             }
5442         }
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int filterCallingUid, int userId)5443         public final ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName,
5444                 int flags, int filterCallingUid, int userId) {
5445             ThreadComputer current = live();
5446             try {
5447                 return current.mComputer.generateApplicationInfoFromSettingsLPw(packageName, flags,
5448                         filterCallingUid, userId);
5449             } finally {
5450                 current.release();
5451             }
5452         }
getApplicationInfo(String packageName, int flags, int userId)5453         public final ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
5454             ThreadComputer current = snapshot();
5455             try {
5456                 return current.mComputer.getApplicationInfo(packageName, flags, userId);
5457             } finally {
5458                 current.release();
5459             }
5460         }
getApplicationInfoInternal(String packageName, int flags, int filterCallingUid, int userId)5461         public final ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
5462                 int filterCallingUid, int userId) {
5463             ThreadComputer current = live();
5464             try {
5465                 return current.mComputer.getApplicationInfoInternal(packageName, flags,
5466                         filterCallingUid, userId);
5467             } finally {
5468                 current.release();
5469             }
5470         }
getDefaultHomeActivity(int userId)5471         public final ComponentName getDefaultHomeActivity(int userId) {
5472             ThreadComputer current = live();
5473             try {
5474                 return current.mComputer.getDefaultHomeActivity(userId);
5475             } finally {
5476                 current.release();
5477             }
5478         }
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)5479         public final ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
5480                 int userId) {
5481             ThreadComputer current = live();
5482             try {
5483                 return current.mComputer.getHomeActivitiesAsUser(allHomeCandidates, userId);
5484             } finally {
5485                 current.release();
5486             }
5487         }
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)5488         public final CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
5489                 String resolvedType, int flags, int sourceUserId, int parentUserId) {
5490             ThreadComputer current = live();
5491             try {
5492                 return current.mComputer.getCrossProfileDomainPreferredLpr(intent, resolvedType,
5493                         flags, sourceUserId, parentUserId);
5494             } finally {
5495                 current.release();
5496             }
5497         }
getHomeIntent()5498         public final Intent getHomeIntent() {
5499             ThreadComputer current = live();
5500             try {
5501                 return current.mComputer.getHomeIntent();
5502             } finally {
5503                 current.release();
5504             }
5505         }
getMatchingCrossProfileIntentFilters( Intent intent, String resolvedType, int userId)5506         public final List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(
5507                 Intent intent, String resolvedType, int userId) {
5508             ThreadComputer current = live();
5509             try {
5510                 return current.mComputer.getMatchingCrossProfileIntentFilters(intent, resolvedType,
5511                         userId);
5512             } finally {
5513                 current.release();
5514             }
5515         }
applyPostResolutionFilter( @onNull List<ResolveInfo> resolveInfos, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, boolean resolveForStart, int userId, Intent intent)5516         public final List<ResolveInfo> applyPostResolutionFilter(
5517                 @NonNull List<ResolveInfo> resolveInfos,
5518                 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
5519                 boolean resolveForStart, int userId, Intent intent) {
5520             ThreadComputer current = live();
5521             try {
5522                 return current.mComputer.applyPostResolutionFilter(resolveInfos, ephemeralPkgName,
5523                         allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);
5524             } finally {
5525                 current.release();
5526             }
5527         }
generatePackageInfo(PackageSetting ps, int flags, int userId)5528         public final PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
5529             ThreadComputer current = live();
5530             try {
5531                 return current.mComputer.generatePackageInfo(ps, flags, userId);
5532             } finally {
5533                 current.release();
5534             }
5535         }
getPackageInfo(String packageName, int flags, int userId)5536         public final PackageInfo getPackageInfo(String packageName, int flags, int userId) {
5537             ThreadComputer current = snapshot();
5538             try {
5539                 return current.mComputer.getPackageInfo(packageName, flags, userId);
5540             } finally {
5541                 current.release();
5542             }
5543         }
getPackageInfoInternal(String packageName, long versionCode, int flags, int filterCallingUid, int userId)5544         public final PackageInfo getPackageInfoInternal(String packageName, long versionCode,
5545                 int flags, int filterCallingUid, int userId) {
5546             ThreadComputer current = live();
5547             try {
5548                 return current.mComputer.getPackageInfoInternal(packageName, versionCode, flags,
5549                         filterCallingUid, userId);
5550             } finally {
5551                 current.release();
5552             }
5553         }
getPackageSetting(String packageName)5554         public final PackageSetting getPackageSetting(String packageName) {
5555             ThreadComputer current = snapshot();
5556             try {
5557                 return current.mComputer.getPackageSetting(packageName);
5558             } finally {
5559                 current.release();
5560             }
5561         }
getPackageSettingInternal(String packageName, int callingUid)5562         public final PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
5563             ThreadComputer current = live();
5564             try {
5565                 return current.mComputer.getPackageSettingInternal(packageName, callingUid);
5566             } finally {
5567                 current.release();
5568             }
5569         }
getInstalledPackages(int flags, int userId)5570         public final ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
5571             ThreadComputer current = snapshot();
5572             try {
5573                 return current.mComputer.getInstalledPackages(flags, userId);
5574             } finally {
5575                 current.release();
5576             }
5577         }
createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, int sourceUserId, int targetUserId)5578         public final ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
5579                 int sourceUserId, int targetUserId) {
5580             ThreadComputer current = live();
5581             try {
5582                 return current.mComputer.createForwardingResolveInfoUnchecked(filter, sourceUserId,
5583                         targetUserId);
5584             } finally {
5585                 current.release();
5586             }
5587         }
getServiceInfo(ComponentName component, int flags, int userId)5588         public final ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5589             ThreadComputer current = live();
5590             try {
5591                 return current.mComputer.getServiceInfo(component, flags, userId);
5592             } finally {
5593                 current.release();
5594             }
5595         }
getSharedLibraryInfoLPr(String name, long version)5596         public final SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
5597             ThreadComputer current = live();
5598             try {
5599                 return current.mComputer.getSharedLibraryInfoLPr(name, version);
5600             } finally {
5601                 current.release();
5602             }
5603         }
getSigningDetails(@onNull String packageName)5604         public final SigningDetails getSigningDetails(@NonNull String packageName) {
5605             ThreadComputer current = snapshot();
5606             try {
5607                 return current.mComputer.getSigningDetails(packageName);
5608             } finally {
5609                 current.release();
5610             }
5611         }
getSigningDetails(int uid)5612         public final SigningDetails getSigningDetails(int uid) {
5613             ThreadComputer current = snapshot();
5614             try {
5615                 return current.mComputer.getSigningDetails(uid);
5616             } finally {
5617                 current.release();
5618             }
5619         }
getInstantAppPackageName(int callingUid)5620         public final String getInstantAppPackageName(int callingUid) {
5621             ThreadComputer current = snapshot();
5622             try {
5623                 return current.mComputer.getInstantAppPackageName(callingUid);
5624             } finally {
5625                 current.release();
5626             }
5627         }
resolveExternalPackageNameLPr(AndroidPackage pkg)5628         public final String resolveExternalPackageNameLPr(AndroidPackage pkg) {
5629             ThreadComputer current = live();
5630             try {
5631                 return current.mComputer.resolveExternalPackageNameLPr(pkg);
5632             } finally {
5633                 current.release();
5634             }
5635         }
resolveInternalPackageNameLPr(String packageName, long versionCode)5636         public final String resolveInternalPackageNameLPr(String packageName, long versionCode) {
5637             ThreadComputer current = live();
5638             try {
5639                 return current.mComputer.resolveInternalPackageNameLPr(packageName, versionCode);
5640             } finally {
5641                 current.release();
5642             }
5643         }
getPackagesForUid(int uid)5644         public final String[] getPackagesForUid(int uid) {
5645             ThreadComputer current = snapshot();
5646             try {
5647                 return current.mComputer.getPackagesForUid(uid);
5648             } finally {
5649                 current.release();
5650             }
5651         }
getProfileParent(int userId)5652         public final UserInfo getProfileParent(int userId) {
5653             ThreadComputer current = live();
5654             try {
5655                 return current.mComputer.getProfileParent(userId);
5656             } finally {
5657                 current.release();
5658             }
5659         }
canViewInstantApps(int callingUid, int userId)5660         public final boolean canViewInstantApps(int callingUid, int userId) {
5661             ThreadComputer current = live();
5662             try {
5663                 return current.mComputer.canViewInstantApps(callingUid, userId);
5664             } finally {
5665                 current.release();
5666             }
5667         }
filterAppAccess(AndroidPackage pkg, int callingUid, int userId)5668         public final boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
5669             ThreadComputer current = snapshot();
5670             try {
5671                 return current.mComputer.filterAppAccess(pkg, callingUid, userId);
5672             } finally {
5673                 current.release();
5674             }
5675         }
filterAppAccess(String packageName, int callingUid, int userId)5676         public final boolean filterAppAccess(String packageName, int callingUid, int userId) {
5677             ThreadComputer current = snapshot();
5678             try {
5679                 return current.mComputer.filterAppAccess(packageName, callingUid, userId);
5680             } finally {
5681                 current.release();
5682             }
5683         }
filterSharedLibPackageLPr(@ullable PackageSetting ps, int uid, int userId, int flags)5684         public final boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid,
5685                 int userId, int flags) {
5686             ThreadComputer current = live();
5687             try {
5688                 return current.mComputer.filterSharedLibPackageLPr(ps, uid, userId, flags);
5689             } finally {
5690                 current.release();
5691             }
5692         }
isCallerSameApp(String packageName, int uid)5693         public final boolean isCallerSameApp(String packageName, int uid) {
5694             ThreadComputer current = live();
5695             try {
5696                 return current.mComputer.isCallerSameApp(packageName, uid);
5697             } finally {
5698                 current.release();
5699             }
5700         }
isComponentVisibleToInstantApp(@ullable ComponentName component)5701         public final boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
5702             ThreadComputer current = live();
5703             try {
5704                 return current.mComputer.isComponentVisibleToInstantApp(component);
5705             } finally {
5706                 current.release();
5707             }
5708         }
isComponentVisibleToInstantApp(@ullable ComponentName component, @ComponentType int type)5709         public final boolean isComponentVisibleToInstantApp(@Nullable ComponentName component,
5710                 @ComponentType int type) {
5711             ThreadComputer current = live();
5712             try {
5713                 return current.mComputer.isComponentVisibleToInstantApp(component, type);
5714             } finally {
5715                 current.release();
5716             }
5717         }
isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, String resolvedType, int flags)5718         public final boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
5719                 int userId, String resolvedType, int flags) {
5720             ThreadComputer current = live();
5721             try {
5722                 return current.mComputer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent,
5723                         userId, resolvedType, flags);
5724             } finally {
5725                 current.release();
5726             }
5727         }
isInstantApp(String packageName, int userId)5728         public final boolean isInstantApp(String packageName, int userId) {
5729             ThreadComputer current = snapshot();
5730             try {
5731                 return current.mComputer.isInstantApp(packageName, userId);
5732             } finally {
5733                 current.release();
5734             }
5735         }
isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid)5736         public final boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
5737                 int callingUid) {
5738             ThreadComputer current = live();
5739             try {
5740                 return current.mComputer.isInstantAppInternal(packageName, userId, callingUid);
5741             } finally {
5742                 current.release();
5743             }
5744         }
isSameProfileGroup(@serIdInt int callerUserId, @UserIdInt int userId)5745         public final boolean isSameProfileGroup(@UserIdInt int callerUserId,
5746                 @UserIdInt int userId) {
5747             ThreadComputer current = live();
5748             try {
5749                 return current.mComputer.isSameProfileGroup(callerUserId, userId);
5750             } finally {
5751                 current.release();
5752             }
5753         }
shouldFilterApplicationLocked(@onNull SharedUserSetting sus, int callingUid, int userId)5754         public final boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus,
5755                 int callingUid, int userId) {
5756             ThreadComputer current = live();
5757             try {
5758                 return current.mComputer.shouldFilterApplicationLocked(sus, callingUid, userId);
5759             } finally {
5760                 current.release();
5761             }
5762         }
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, @Nullable ComponentName component, @ComponentType int componentType, int userId)5763         public final boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps,
5764                 int callingUid,
5765                 @Nullable ComponentName component, @ComponentType int componentType, int userId) {
5766             ThreadComputer current = live();
5767             try {
5768                 return current.mComputer.shouldFilterApplicationLocked(ps, callingUid, component,
5769                         componentType, userId);
5770             } finally {
5771                 current.release();
5772             }
5773         }
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, int userId)5774         public final boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps,
5775                 int callingUid, int userId) {
5776             ThreadComputer current = live();
5777             try {
5778                 return current.mComputer.shouldFilterApplicationLocked(ps, callingUid, userId);
5779             } finally {
5780                 current.release();
5781             }
5782         }
checkUidPermission(String permName, int uid)5783         public final int checkUidPermission(String permName, int uid) {
5784             ThreadComputer current = snapshot();
5785             try {
5786                 return current.mComputer.checkUidPermission(permName, uid);
5787             } finally {
5788                 current.release();
5789             }
5790         }
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)5791         public final int getPackageUidInternal(String packageName, int flags, int userId,
5792                 int callingUid) {
5793             ThreadComputer current = live();
5794             try {
5795                 return current.mComputer.getPackageUidInternal(packageName, flags, userId,
5796                         callingUid);
5797             } finally {
5798                 current.release();
5799             }
5800         }
updateFlagsForApplication(int flags, int userId)5801         public final int updateFlagsForApplication(int flags, int userId) {
5802             ThreadComputer current = live();
5803             try {
5804                 return current.mComputer.updateFlagsForApplication(flags, userId);
5805             } finally {
5806                 current.release();
5807             }
5808         }
updateFlagsForComponent(int flags, int userId)5809         public final int updateFlagsForComponent(int flags, int userId) {
5810             ThreadComputer current = live();
5811             try {
5812                 return current.mComputer.updateFlagsForComponent(flags, userId);
5813             } finally {
5814                 current.release();
5815             }
5816         }
updateFlagsForPackage(int flags, int userId)5817         public final int updateFlagsForPackage(int flags, int userId) {
5818             ThreadComputer current = live();
5819             try {
5820                 return current.mComputer.updateFlagsForPackage(flags, userId);
5821             } finally {
5822                 current.release();
5823             }
5824         }
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc)5825         public final int updateFlagsForResolve(int flags, int userId, int callingUid,
5826                 boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
5827             ThreadComputer current = live();
5828             try {
5829                 return current.mComputer.updateFlagsForResolve(flags, userId, callingUid,
5830                         wantInstantApps, isImplicitImageCaptureIntentAndNotSetByDpc);
5831             } finally {
5832                 current.release();
5833             }
5834         }
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc)5835         public final int updateFlagsForResolve(int flags, int userId, int callingUid,
5836                 boolean wantInstantApps, boolean onlyExposedExplicitly,
5837                 boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
5838             ThreadComputer current = live();
5839             try {
5840                 return current.mComputer.updateFlagsForResolve(flags, userId, callingUid,
5841                         wantInstantApps, onlyExposedExplicitly,
5842                         isImplicitImageCaptureIntentAndNotSetByDpc);
5843             } finally {
5844                 current.release();
5845             }
5846         }
dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState)5847         public final void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
5848             ThreadComputer current = live();
5849             try {
5850                 current.mComputer.dump(type, fd, pw, dumpState);
5851             } finally {
5852                 current.release();
5853             }
5854         }
enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)5855         public final void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
5856                 boolean requireFullPermission, boolean checkShell, String message) {
5857             ThreadComputer current = live();
5858             try {
5859                 current.mComputer.enforceCrossUserOrProfilePermission(callingUid, userId,
5860                         requireFullPermission, checkShell, message);
5861             } finally {
5862                 current.release();
5863             }
5864         }
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)5865         public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
5866                 boolean requireFullPermission, boolean checkShell, String message) {
5867             ThreadComputer current = live();
5868             try {
5869                 current.mComputer.enforceCrossUserPermission(callingUid, userId,
5870                         requireFullPermission, checkShell, message);
5871             } finally {
5872                 current.release();
5873             }
5874         }
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)5875         public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
5876                 boolean requireFullPermission, boolean checkShell,
5877                 boolean requirePermissionWhenSameUser, String message) {
5878             ThreadComputer current = live();
5879             try {
5880                 current.mComputer.enforceCrossUserPermission(callingUid, userId,
5881                         requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
5882             } finally {
5883                 current.release();
5884             }
5885         }
findPreferredActivityInternal(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered)5886         public final FindPreferredActivityBodyResult findPreferredActivityInternal(Intent intent,
5887                 String resolvedType, int flags, List<ResolveInfo> query, boolean always,
5888                 boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
5889             ThreadComputer current = live();
5890             try {
5891                 return current.mComputer.findPreferredActivityInternal(intent, resolvedType, flags,
5892                         query, always, removeMatches, debug, userId, queryMayBeFiltered);
5893             } finally {
5894                 current.release();
5895             }
5896         }
findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)5897         public final ResolveInfo findPersistentPreferredActivityLP(Intent intent,
5898                 String resolvedType, int flags, List<ResolveInfo> query, boolean debug,
5899                 int userId) {
5900             ThreadComputer current = live();
5901             try {
5902                 return current.mComputer.findPersistentPreferredActivityLP(intent, resolvedType,
5903                         flags, query, debug, userId);
5904             } finally {
5905                 current.release();
5906             }
5907         }
5908     }
5909 
5910 
5911     // Compute read-only functions, based on live data.  This attribute may be modified multiple
5912     // times during the PackageManagerService constructor but it should not be modified thereafter.
5913     private ComputerLocked mLiveComputer;
5914 
5915     // A lock-free cache for frequently called functions.
5916     private volatile Computer mSnapshotComputer;
5917 
5918     // A trampoline that directs callers to either the live or snapshot computer.
5919     private final ComputerTracker mComputer = new ComputerTracker(this);
5920 
5921     // If true, the snapshot is invalid (stale).  The attribute is static since it may be
5922     // set from outside classes.  The attribute may be set to true anywhere, although it
5923     // should only be set true while holding mLock.  However, the attribute id guaranteed
5924     // to be set false only while mLock and mSnapshotLock are both held.
5925     private static AtomicBoolean sSnapshotInvalid = new AtomicBoolean(true);
5926     // The package manager that is using snapshots.
5927     private static PackageManagerService sSnapshotConsumer = null;
5928     // If true, the snapshot is corked.  Do not create a new snapshot but use the live
5929     // computer.  This throttles snapshot creation during periods of churn in Package
5930     // Manager.
5931     private static AtomicInteger sSnapshotCorked = new AtomicInteger(0);
5932 
5933     /**
5934      * This class records the Computer being used by a thread and the Computer's reference
5935      * count.  There is a thread-local copy of this class.
5936      */
5937     private static class ThreadComputer {
5938         Computer mComputer = null;
5939         int mRefCount = 0;
acquire(Computer c)5940         void acquire(Computer c) {
5941             if (mRefCount != 0 && mComputer != c) {
5942                 throw new RuntimeException("computer mismatch, count = " + mRefCount);
5943             }
5944             mComputer = c;
5945             mRefCount++;
5946         }
acquire()5947         void acquire() {
5948             if (mRefCount == 0 || mComputer == null) {
5949                 throw new RuntimeException("computer acquire on empty ref count");
5950             }
5951             mRefCount++;
5952         }
release()5953         void release() {
5954             if (--mRefCount == 0) {
5955                 mComputer = null;
5956             }
5957         }
5958     }
5959     private static ThreadLocal<ThreadComputer> sThreadComputer = new ThreadLocal<>() {
5960             @Override protected ThreadComputer initialValue() {
5961                 return new ThreadComputer();
5962             }};
5963 
5964     /**
5965      * This lock is used to make reads from {@link #sSnapshotInvalid} and
5966      * {@link #mSnapshotComputer} atomic inside {@code snapshotComputer()}.  This lock is
5967      * not meant to be used outside that method.  This lock must be taken before
5968      * {@link #mLock} is taken.
5969      */
5970     private final Object mSnapshotLock = new Object();
5971 
5972     /**
5973      * The snapshot statistics.  These are collected to track performance and to identify
5974      * situations in which the snapshots are misbehaving.
5975      */
5976     private final SnapshotStatistics mSnapshotStatistics;
5977 
5978     // The snapshot disable/enable switch.  An image with the flag set true uses snapshots
5979     // and an image with the flag set false does not use snapshots.
5980     private static final boolean SNAPSHOT_ENABLED = true;
5981 
5982     // The default auto-cork delay for snapshots.  This is 1s.
5983     private static final long SNAPSHOT_AUTOCORK_DELAY_MS = TimeUnit.SECONDS.toMillis(1);
5984 
5985     // The per-instance snapshot disable/enable flag.  This is generally set to false in
5986     // test instances and set to SNAPSHOT_ENABLED in operational instances.
5987     private final boolean mSnapshotEnabled;
5988 
5989     /**
5990      * Return the live computer.
5991      */
liveComputer()5992     private Computer liveComputer() {
5993         return mLiveComputer;
5994     }
5995 
5996     /**
5997      * Return the cached computer.  The method will rebuild the cached computer if necessary.
5998      * The live computer will be returned if snapshots are disabled.
5999      */
snapshotComputer()6000     private Computer snapshotComputer() {
6001         if (!mSnapshotEnabled) {
6002             return mLiveComputer;
6003         }
6004         if (Thread.holdsLock(mLock)) {
6005             // If the current thread holds mLock then it may have modified state but not
6006             // yet invalidated the snapshot.  Always give the thread the live computer.
6007             return mLiveComputer;
6008         } else if (sSnapshotCorked.get() > 0) {
6009             // Snapshots are corked, which means new ones should not be built right now.
6010             mSnapshotStatistics.corked();
6011             return mLiveComputer;
6012         }
6013         synchronized (mSnapshotLock) {
6014             // This synchronization block serializes access to the snapshot computer and
6015             // to the code that samples mSnapshotInvalid.
6016             Computer c = mSnapshotComputer;
6017             if (sSnapshotInvalid.getAndSet(false) || (c == null)) {
6018                 // The snapshot is invalid if it is marked as invalid or if it is null.  If it
6019                 // is null, then it is currently being rebuilt by rebuildSnapshot().
6020                 synchronized (mLock) {
6021                     // Rebuild the snapshot if it is invalid.  Note that the snapshot might be
6022                     // invalidated as it is rebuilt.  However, the snapshot is still
6023                     // self-consistent (the lock is being held) and is current as of the time
6024                     // this function is entered.
6025                     rebuildSnapshot();
6026 
6027                     // Guaranteed to be non-null.  mSnapshotComputer is only be set to null
6028                     // temporarily in rebuildSnapshot(), which is guarded by mLock().  Since
6029                     // the mLock is held in this block and since rebuildSnapshot() is
6030                     // complete, the attribute can not now be null.
6031                     c = mSnapshotComputer;
6032                 }
6033             }
6034             c.use();
6035             return c;
6036         }
6037     }
6038 
6039     /**
6040      * Rebuild the cached computer.  mSnapshotComputer is temporarily set to null to block other
6041      * threads from using the invalid computer until it is rebuilt.
6042      */
6043     @GuardedBy({ "mLock", "mSnapshotLock"})
rebuildSnapshot()6044     private void rebuildSnapshot() {
6045         final long now = SystemClock.currentTimeMicro();
6046         final int hits = mSnapshotComputer == null ? -1 : mSnapshotComputer.getUsed();
6047         mSnapshotComputer = null;
6048         final Snapshot args = new Snapshot(Snapshot.SNAPPED);
6049         mSnapshotComputer = new ComputerEngine(args);
6050         final long done = SystemClock.currentTimeMicro();
6051 
6052         mSnapshotStatistics.rebuild(now, done, hits);
6053     }
6054 
6055     /**
6056      * Create a new snapshot.  Used for testing only.  This does collect statistics or
6057      * update the snapshot used by other actors.  It does not alter the invalidation
6058      * flag.  This method takes the mLock internally.
6059      */
createNewSnapshot()6060     private Computer createNewSnapshot() {
6061         synchronized (mLock) {
6062             final Snapshot args = new Snapshot(Snapshot.SNAPPED);
6063             return new ComputerEngine(args);
6064         }
6065     }
6066 
6067     /**
6068      * Cork snapshots.  This times out after the programmed delay.
6069      */
corkSnapshots(int multiplier)6070     private void corkSnapshots(int multiplier) {
6071         int corking = sSnapshotCorked.getAndIncrement();
6072         if (TRACE_SNAPSHOTS && corking == 0) {
6073             Log.i(TAG, "snapshot: corking goes positive");
6074         }
6075         Message message = mHandler.obtainMessage(SNAPSHOT_UNCORK);
6076         mHandler.sendMessageDelayed(message, SNAPSHOT_AUTOCORK_DELAY_MS * multiplier);
6077     }
6078 
6079     /**
6080      * Create a live computer
6081      */
createLiveComputer()6082     private ComputerLocked createLiveComputer() {
6083         return new ComputerLocked(new Snapshot(Snapshot.LIVE));
6084     }
6085 
6086     /**
6087      * This method is called when the state of PackageManagerService changes so as to
6088      * invalidate the current snapshot.
6089      * @param what The {@link Watchable} that reported the change
6090      * @hide
6091      */
onChange(@ullable Watchable what)6092     public static void onChange(@Nullable Watchable what) {
6093         if (TRACE_SNAPSHOTS) {
6094             Log.i(TAG, "snapshot: onChange(" + what + ")");
6095         }
6096         sSnapshotInvalid.set(true);
6097     }
6098 
6099     /**
6100      * Report a locally-detected change to observers.  The <what> parameter is left null,
6101      * but it signifies that the change was detected by PackageManagerService itself.
6102      */
onChanged()6103     private static void onChanged() {
6104         onChange(null);
6105     }
6106 
6107     class PackageHandler extends Handler {
6108 
PackageHandler(Looper looper)6109         PackageHandler(Looper looper) {
6110             super(looper);
6111         }
6112 
handleMessage(Message msg)6113         public void handleMessage(Message msg) {
6114             try {
6115                 doHandleMessage(msg);
6116             } finally {
6117                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
6118             }
6119         }
6120 
doHandleMessage(Message msg)6121         void doHandleMessage(Message msg) {
6122             switch (msg.what) {
6123                 case INIT_COPY: {
6124                     HandlerParams params = (HandlerParams) msg.obj;
6125                     if (params != null) {
6126                         if (DEBUG_INSTALL) Slog.i(TAG, "init_copy: " + params);
6127                         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
6128                                 System.identityHashCode(params));
6129                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
6130                         params.startCopy();
6131                         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6132                     }
6133                     break;
6134                 }
6135                 case SEND_PENDING_BROADCAST: {
6136                     String packages[];
6137                     ArrayList<String> components[];
6138                     int size = 0;
6139                     int uids[];
6140                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
6141                     synchronized (mLock) {
6142                         size = mPendingBroadcasts.size();
6143                         if (size <= 0) {
6144                             // Nothing to be done. Just return
6145                             return;
6146                         }
6147                         packages = new String[size];
6148                         components = new ArrayList[size];
6149                         uids = new int[size];
6150                         int i = 0;  // filling out the above arrays
6151 
6152                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
6153                             final int packageUserId = mPendingBroadcasts.userIdAt(n);
6154                             final ArrayMap<String, ArrayList<String>> componentsToBroadcast =
6155                                     mPendingBroadcasts.packagesForUserId(packageUserId);
6156                             final int numComponents = componentsToBroadcast.size();
6157                             for (int index = 0; i < size && index < numComponents; index++) {
6158                                 packages[i] = componentsToBroadcast.keyAt(index);
6159                                 components[i] = componentsToBroadcast.valueAt(index);
6160                                 final PackageSetting ps = mSettings.getPackageLPr(packages[i]);
6161                                 uids[i] = (ps != null)
6162                                         ? UserHandle.getUid(packageUserId, ps.appId)
6163                                         : -1;
6164                                 i++;
6165                             }
6166                         }
6167                         size = i;
6168                         mPendingBroadcasts.clear();
6169                     }
6170                     // Send broadcasts
6171                     for (int i = 0; i < size; i++) {
6172                         sendPackageChangedBroadcast(packages[i], true /* dontKillApp */,
6173                                 components[i], uids[i], null /* reason */);
6174                     }
6175                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
6176                     break;
6177                 }
6178                 case POST_INSTALL: {
6179                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
6180 
6181                     PostInstallData data = mRunningInstalls.get(msg.arg1);
6182                     final boolean didRestore = (msg.arg2 != 0);
6183                     mRunningInstalls.delete(msg.arg1);
6184 
6185                     if (data != null && data.res.freezer != null) {
6186                         data.res.freezer.close();
6187                     }
6188 
6189                     if (data != null && data.mPostInstallRunnable != null) {
6190                         data.mPostInstallRunnable.run();
6191                     } else if (data != null && data.args != null) {
6192                         InstallArgs args = data.args;
6193                         PackageInstalledInfo parentRes = data.res;
6194 
6195                         final boolean killApp = (args.installFlags
6196                                 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
6197                         final boolean virtualPreload = ((args.installFlags
6198                                 & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
6199 
6200                         handlePackagePostInstall(parentRes, killApp, virtualPreload,
6201                                 didRestore, args.installSource.installerPackageName, args.observer,
6202                                 args.mDataLoaderType);
6203 
6204                         // Log tracing if needed
6205                         if (args.traceMethod != null) {
6206                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
6207                                     args.traceCookie);
6208                         }
6209                     } else if (DEBUG_INSTALL) {
6210                         // No post-install when we run restore from installExistingPackageForUser
6211                         Slog.i(TAG, "Nothing to do for post-install token " + msg.arg1);
6212                     }
6213 
6214                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
6215                 } break;
6216                 case DEFERRED_NO_KILL_POST_DELETE: {
6217                     synchronized (mInstallLock) {
6218                         InstallArgs args = (InstallArgs) msg.obj;
6219                         if (args != null) {
6220                             args.doPostDeleteLI(true);
6221                         }
6222                     }
6223                 } break;
6224                 case DEFERRED_NO_KILL_INSTALL_OBSERVER: {
6225                     String packageName = (String) msg.obj;
6226                     if (packageName != null) {
6227                         notifyInstallObserver(packageName);
6228                     }
6229                 } break;
6230                 case WRITE_SETTINGS: {
6231                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
6232                     synchronized (mLock) {
6233                         removeMessages(WRITE_SETTINGS);
6234                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
6235                         writeSettingsLPrTEMP();
6236                         mDirtyUsers.clear();
6237                     }
6238                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
6239                 } break;
6240                 case WRITE_PACKAGE_RESTRICTIONS: {
6241                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
6242                     synchronized (mLock) {
6243                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
6244                         for (int userId : mDirtyUsers) {
6245                             mSettings.writePackageRestrictionsLPr(userId);
6246                         }
6247                         mDirtyUsers.clear();
6248                     }
6249                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
6250                 } break;
6251                 case WRITE_PACKAGE_LIST: {
6252                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
6253                     synchronized (mLock) {
6254                         removeMessages(WRITE_PACKAGE_LIST);
6255                         mSettings.writePackageListLPr(msg.arg1);
6256                     }
6257                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
6258                 } break;
6259                 case CHECK_PENDING_VERIFICATION: {
6260                     final int verificationId = msg.arg1;
6261                     final PackageVerificationState state = mPendingVerification.get(verificationId);
6262 
6263                     if ((state != null) && !state.isVerificationComplete()
6264                             && !state.timeoutExtended()) {
6265                         final VerificationParams params = state.getVerificationParams();
6266                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6267 
6268                         Slog.i(TAG, "Verification timed out for " + originUri);
6269 
6270                         final UserHandle user = params.getUser();
6271                         if (getDefaultVerificationResponse(user)
6272                                 == PackageManager.VERIFICATION_ALLOW) {
6273                             Slog.i(TAG, "Continuing with installation of " + originUri);
6274                             state.setVerifierResponse(Binder.getCallingUid(),
6275                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
6276                             broadcastPackageVerified(verificationId, originUri,
6277                                     PackageManager.VERIFICATION_ALLOW, null, params.mDataLoaderType,
6278                                     user);
6279                         } else {
6280                             broadcastPackageVerified(verificationId, originUri,
6281                                     PackageManager.VERIFICATION_REJECT, null,
6282                                     params.mDataLoaderType, user);
6283                             params.setReturnCode(
6284                                     PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
6285                             state.setVerifierResponse(Binder.getCallingUid(),
6286                                     PackageManager.VERIFICATION_REJECT);
6287                         }
6288 
6289                         if (state.areAllVerificationsComplete()) {
6290                             mPendingVerification.remove(verificationId);
6291                         }
6292 
6293                         Trace.asyncTraceEnd(
6294                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
6295 
6296                         params.handleVerificationFinished();
6297 
6298                     }
6299                     break;
6300                 }
6301                 case CHECK_PENDING_INTEGRITY_VERIFICATION: {
6302                     final int verificationId = msg.arg1;
6303                     final PackageVerificationState state = mPendingVerification.get(verificationId);
6304 
6305                     if (state != null && !state.isIntegrityVerificationComplete()) {
6306                         final VerificationParams params = state.getVerificationParams();
6307                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6308 
6309                         Slog.i(TAG, "Integrity verification timed out for " + originUri);
6310 
6311                         state.setIntegrityVerificationResult(
6312                                 getDefaultIntegrityVerificationResponse());
6313 
6314                         if (getDefaultIntegrityVerificationResponse()
6315                                 == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
6316                             Slog.i(TAG, "Integrity check times out, continuing with " + originUri);
6317                         } else {
6318                             params.setReturnCode(
6319                                     PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
6320                         }
6321 
6322                         if (state.areAllVerificationsComplete()) {
6323                             mPendingVerification.remove(verificationId);
6324                         }
6325 
6326                         Trace.asyncTraceEnd(
6327                                 TRACE_TAG_PACKAGE_MANAGER,
6328                                 "integrity_verification",
6329                                 verificationId);
6330 
6331                         params.handleIntegrityVerificationFinished();
6332                     }
6333                     break;
6334                 }
6335                 case PACKAGE_VERIFIED: {
6336                     final int verificationId = msg.arg1;
6337 
6338                     final PackageVerificationState state = mPendingVerification.get(verificationId);
6339                     if (state == null) {
6340                         Slog.w(TAG, "Verification with id " + verificationId
6341                                 + " not found."
6342                                 + " It may be invalid or overridden by integrity verification");
6343                         break;
6344                     }
6345 
6346                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
6347 
6348                     state.setVerifierResponse(response.callerUid, response.code);
6349 
6350                     if (state.isVerificationComplete()) {
6351                         final VerificationParams params = state.getVerificationParams();
6352                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6353 
6354                         if (state.isInstallAllowed()) {
6355                             broadcastPackageVerified(verificationId, originUri,
6356                                     response.code, null, params.mDataLoaderType, params.getUser());
6357                         } else {
6358                             params.setReturnCode(
6359                                     PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
6360                         }
6361 
6362                         if (state.areAllVerificationsComplete()) {
6363                             mPendingVerification.remove(verificationId);
6364                         }
6365 
6366                         Trace.asyncTraceEnd(
6367                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
6368 
6369                         params.handleVerificationFinished();
6370                     }
6371 
6372                     break;
6373                 }
6374                 case INTEGRITY_VERIFICATION_COMPLETE: {
6375                     final int verificationId = msg.arg1;
6376 
6377                     final PackageVerificationState state = mPendingVerification.get(verificationId);
6378                     if (state == null) {
6379                         Slog.w(TAG, "Integrity verification with id " + verificationId
6380                                 + " not found. It may be invalid or overridden by verifier");
6381                         break;
6382                     }
6383 
6384                     final int response = (Integer) msg.obj;
6385                     final VerificationParams params = state.getVerificationParams();
6386                     final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6387 
6388                     state.setIntegrityVerificationResult(response);
6389 
6390                     if (response == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
6391                         Slog.i(TAG, "Integrity check passed for " + originUri);
6392                     } else {
6393                         params.setReturnCode(
6394                                 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
6395                     }
6396 
6397                     if (state.areAllVerificationsComplete()) {
6398                         mPendingVerification.remove(verificationId);
6399                     }
6400 
6401                     Trace.asyncTraceEnd(
6402                             TRACE_TAG_PACKAGE_MANAGER,
6403                             "integrity_verification",
6404                             verificationId);
6405 
6406                     params.handleIntegrityVerificationFinished();
6407                     break;
6408                 }
6409                 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
6410                     InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
6411                             mInstantAppResolverConnection,
6412                             (InstantAppRequest) msg.obj,
6413                             mInstantAppInstallerActivity,
6414                             mHandler);
6415                     break;
6416                 }
6417                 case ENABLE_ROLLBACK_STATUS: {
6418                     final int enableRollbackToken = msg.arg1;
6419                     final int enableRollbackCode = msg.arg2;
6420                     final VerificationParams params =
6421                             mPendingEnableRollback.get(enableRollbackToken);
6422                     if (params == null) {
6423                         Slog.w(TAG, "Invalid rollback enabled token "
6424                                 + enableRollbackToken + " received");
6425                         break;
6426                     }
6427 
6428                     mPendingEnableRollback.remove(enableRollbackToken);
6429 
6430                     if (enableRollbackCode != PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED) {
6431                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6432                         Slog.w(TAG, "Failed to enable rollback for " + originUri);
6433                         Slog.w(TAG, "Continuing with installation of " + originUri);
6434                     }
6435 
6436                     Trace.asyncTraceEnd(
6437                             TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
6438 
6439                     params.handleRollbackEnabled();
6440                     break;
6441                 }
6442                 case ENABLE_ROLLBACK_TIMEOUT: {
6443                     final int enableRollbackToken = msg.arg1;
6444                     final int sessionId = msg.arg2;
6445                     final VerificationParams params =
6446                             mPendingEnableRollback.get(enableRollbackToken);
6447                     if (params != null) {
6448                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6449 
6450                         Slog.w(TAG, "Enable rollback timed out for " + originUri);
6451                         mPendingEnableRollback.remove(enableRollbackToken);
6452 
6453                         Slog.w(TAG, "Continuing with installation of " + originUri);
6454                         Trace.asyncTraceEnd(
6455                                 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
6456                         params.handleRollbackEnabled();
6457                         Intent rollbackTimeoutIntent = new Intent(
6458                                 Intent.ACTION_CANCEL_ENABLE_ROLLBACK);
6459                         rollbackTimeoutIntent.putExtra(
6460                                 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID,
6461                                 sessionId);
6462                         rollbackTimeoutIntent.addFlags(
6463                                 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
6464                         mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM,
6465                                 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT);
6466                     }
6467                     break;
6468                 }
6469                 case DOMAIN_VERIFICATION: {
6470                     int messageCode = msg.arg1;
6471                     Object object = msg.obj;
6472                     mDomainVerificationManager.runMessage(messageCode, object);
6473                     break;
6474                 }
6475                 case SNAPSHOT_UNCORK: {
6476                     int corking = sSnapshotCorked.decrementAndGet();
6477                     if (TRACE_SNAPSHOTS && corking == 0) {
6478                         Log.e(TAG, "snapshot: corking goes to zero in message handler");
6479                     }
6480                     break;
6481                 }
6482             }
6483         }
6484     }
6485 
handlePackagePostInstall(PackageInstalledInfo res, boolean killApp, boolean virtualPreload, boolean launchedForRestore, String installerPackage, IPackageInstallObserver2 installObserver, int dataLoaderType)6486     private void handlePackagePostInstall(PackageInstalledInfo res, boolean killApp,
6487             boolean virtualPreload, boolean launchedForRestore, String installerPackage,
6488             IPackageInstallObserver2 installObserver, int dataLoaderType) {
6489         boolean succeeded = res.returnCode == PackageManager.INSTALL_SUCCEEDED;
6490         final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null;
6491         final String packageName = res.name;
6492         final PackageSetting pkgSetting = succeeded ? getPackageSetting(packageName) : null;
6493         final boolean removedBeforeUpdate = (pkgSetting == null)
6494                 || (pkgSetting.isSystem() && !pkgSetting.getPathString().equals(res.pkg.getPath()));
6495         if (succeeded && removedBeforeUpdate) {
6496             Slog.e(TAG, packageName + " was removed before handlePackagePostInstall "
6497                     + "could be executed");
6498             res.returnCode = INSTALL_FAILED_PACKAGE_CHANGED;
6499             res.returnMsg = "Package was removed before install could complete.";
6500 
6501             // Remove the update failed package's older resources safely now
6502             InstallArgs args = res.removedInfo != null ? res.removedInfo.args : null;
6503             if (args != null) {
6504                 synchronized (mInstallLock) {
6505                     args.doPostDeleteLI(true);
6506                 }
6507             }
6508             notifyInstallObserver(res, installObserver);
6509             return;
6510         }
6511 
6512         if (succeeded) {
6513             // Clear the uid cache after we installed a new package.
6514             mPerUidReadTimeoutsCache = null;
6515 
6516             // Send the removed broadcasts
6517             if (res.removedInfo != null) {
6518                 res.removedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/);
6519             }
6520 
6521             final String installerPackageName =
6522                     res.installerPackageName != null
6523                             ? res.installerPackageName
6524                             : res.removedInfo != null
6525                                     ? res.removedInfo.installerPackageName
6526                                     : null;
6527 
6528             synchronized (mLock) {
6529                 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
6530             }
6531 
6532             // Determine the set of users who are adding this package for
6533             // the first time vs. those who are seeing an update.
6534             int[] firstUserIds = EMPTY_INT_ARRAY;
6535             int[] firstInstantUserIds = EMPTY_INT_ARRAY;
6536             int[] updateUserIds = EMPTY_INT_ARRAY;
6537             int[] instantUserIds = EMPTY_INT_ARRAY;
6538             final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
6539             final PackageSetting ps = pkgSetting;
6540             for (int newUser : res.newUsers) {
6541                 final boolean isInstantApp = ps.getInstantApp(newUser);
6542                 if (allNewUsers) {
6543                     if (isInstantApp) {
6544                         firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
6545                     } else {
6546                         firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
6547                     }
6548                     continue;
6549                 }
6550                 boolean isNew = true;
6551                 for (int origUser : res.origUsers) {
6552                     if (origUser == newUser) {
6553                         isNew = false;
6554                         break;
6555                     }
6556                 }
6557                 if (isNew) {
6558                     if (isInstantApp) {
6559                         firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
6560                     } else {
6561                         firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
6562                     }
6563                 } else {
6564                     if (isInstantApp) {
6565                         instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
6566                     } else {
6567                         updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
6568                     }
6569                 }
6570             }
6571 
6572             // Send installed broadcasts if the package is not a static shared lib.
6573             if (res.pkg.getStaticSharedLibName() == null) {
6574                 mProcessLoggingHandler.invalidateBaseApkHash(res.pkg.getBaseApkPath());
6575 
6576                 // Send added for users that see the package for the first time
6577                 // sendPackageAddedForNewUsers also deals with system apps
6578                 int appId = UserHandle.getAppId(res.uid);
6579                 boolean isSystem = res.pkg.isSystem();
6580                 sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
6581                         virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds,
6582                         dataLoaderType);
6583 
6584                 // Send added for users that don't see the package for the first time
6585                 Bundle extras = new Bundle(1);
6586                 extras.putInt(Intent.EXTRA_UID, res.uid);
6587                 if (update) {
6588                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
6589                 }
6590                 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
6591                 // Send to all running apps.
6592                 final SparseArray<int[]> newBroadcastAllowList;
6593 
6594                 synchronized (mLock) {
6595                     newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
6596                             getPackageSettingInternal(res.name, Process.SYSTEM_UID),
6597                             updateUserIds, mSettings.getPackagesLocked());
6598                 }
6599                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
6600                         extras, 0 /*flags*/,
6601                         null /*targetPackage*/, null /*finishedReceiver*/,
6602                         updateUserIds, instantUserIds, newBroadcastAllowList, null);
6603                 if (installerPackageName != null) {
6604                     // Send to the installer, even if it's not running.
6605                     sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
6606                             extras, 0 /*flags*/,
6607                             installerPackageName, null /*finishedReceiver*/,
6608                             updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
6609                 }
6610                 // if the required verifier is defined, but, is not the installer of record
6611                 // for the package, it gets notified
6612                 final boolean notifyVerifier = mRequiredVerifierPackage != null
6613                         && !mRequiredVerifierPackage.equals(installerPackageName);
6614                 if (notifyVerifier) {
6615                     sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
6616                             extras, 0 /*flags*/,
6617                             mRequiredVerifierPackage, null /*finishedReceiver*/,
6618                             updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
6619                 }
6620                 // If package installer is defined, notify package installer about new
6621                 // app installed
6622                 if (mRequiredInstallerPackage != null) {
6623                     sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
6624                             extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
6625                             mRequiredInstallerPackage, null /*finishedReceiver*/,
6626                             firstUserIds, instantUserIds, null /* broadcastAllowList */, null);
6627                 }
6628 
6629                 // Send replaced for users that don't see the package for the first time
6630                 if (update) {
6631                     sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
6632                             packageName, extras, 0 /*flags*/,
6633                             null /*targetPackage*/, null /*finishedReceiver*/,
6634                             updateUserIds, instantUserIds, res.removedInfo.broadcastAllowList,
6635                             null);
6636                     if (installerPackageName != null) {
6637                         sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
6638                                 extras, 0 /*flags*/,
6639                                 installerPackageName, null /*finishedReceiver*/,
6640                                 updateUserIds, instantUserIds, null /*broadcastAllowList*/, null);
6641                     }
6642                     if (notifyVerifier) {
6643                         sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
6644                                 extras, 0 /*flags*/,
6645                                 mRequiredVerifierPackage, null /*finishedReceiver*/,
6646                                 updateUserIds, instantUserIds, null /*broadcastAllowList*/, null);
6647                     }
6648                     sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
6649                             null /*package*/, null /*extras*/, 0 /*flags*/,
6650                             packageName /*targetPackage*/,
6651                             null /*finishedReceiver*/, updateUserIds, instantUserIds,
6652                             null /*broadcastAllowList*/,
6653                             getTemporaryAppAllowlistBroadcastOptions(REASON_PACKAGE_REPLACED)
6654                                     .toBundle());
6655                 } else if (launchedForRestore && !res.pkg.isSystem()) {
6656                     // First-install and we did a restore, so we're responsible for the
6657                     // first-launch broadcast.
6658                     if (DEBUG_BACKUP) {
6659                         Slog.i(TAG, "Post-restore of " + packageName
6660                                 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
6661                     }
6662                     sendFirstLaunchBroadcast(packageName, installerPackage,
6663                             firstUserIds, firstInstantUserIds);
6664                 }
6665 
6666                 // Send broadcast package appeared if external for all users
6667                 if (res.pkg.isExternalStorage()) {
6668                     if (!update) {
6669                         final StorageManager storage = mInjector.getSystemService(
6670                                 StorageManager.class);
6671                         VolumeInfo volume =
6672                                 storage.findVolumeByUuid(
6673                                         res.pkg.getStorageUuid().toString());
6674                         int packageExternalStorageType =
6675                                 getPackageExternalStorageType(volume, res.pkg.isExternalStorage());
6676                         // If the package was installed externally, log it.
6677                         if (packageExternalStorageType != StorageEnums.UNKNOWN) {
6678                             FrameworkStatsLog.write(
6679                                     FrameworkStatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
6680                                     packageExternalStorageType, packageName);
6681                         }
6682                     }
6683                     if (DEBUG_INSTALL) {
6684                         Slog.i(TAG, "upgrading pkg " + res.pkg + " is external");
6685                     }
6686                     final int[] uidArray = new int[]{res.pkg.getUid()};
6687                     ArrayList<String> pkgList = new ArrayList<>(1);
6688                     pkgList.add(packageName);
6689                     sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
6690                 }
6691             } else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib
6692                 int[] allUsers = mInjector.getUserManagerService().getUserIds();
6693                 for (int i = 0; i < res.libraryConsumers.size(); i++) {
6694                     AndroidPackage pkg = res.libraryConsumers.get(i);
6695                     // send broadcast that all consumers of the static shared library have changed
6696                     sendPackageChangedBroadcast(pkg.getPackageName(), false /* dontKillApp */,
6697                             new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
6698                             pkg.getUid(), null);
6699                 }
6700             }
6701 
6702             // Work that needs to happen on first install within each user
6703             if (firstUserIds != null && firstUserIds.length > 0) {
6704                 for (int userId : firstUserIds) {
6705                     restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
6706                             pkgSetting.getInstallReason(userId), userId);
6707                 }
6708             }
6709 
6710             if (allNewUsers && !update) {
6711                 notifyPackageAdded(packageName, res.uid);
6712             } else {
6713                 notifyPackageChanged(packageName, res.uid);
6714             }
6715 
6716             // Log current value of "unknown sources" setting
6717             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
6718                     getUnknownSourcesSettings());
6719 
6720             // Remove the replaced package's older resources safely now
6721             InstallArgs args = res.removedInfo != null ? res.removedInfo.args : null;
6722             if (args != null) {
6723                 if (!killApp) {
6724                     // If we didn't kill the app, defer the deletion of code/resource files, since
6725                     // they may still be in use by the running application. This mitigates problems
6726                     // in cases where resources or code is loaded by a new Activity before
6727                     // ApplicationInfo changes have propagated to all application threads.
6728                     scheduleDeferredNoKillPostDelete(args);
6729                 } else {
6730                     synchronized (mInstallLock) {
6731                         args.doPostDeleteLI(true);
6732                     }
6733                 }
6734             } else {
6735                 // Force a gc to clear up things. Ask for a background one, it's fine to go on
6736                 // and not block here.
6737                 VMRuntime.getRuntime().requestConcurrentGC();
6738             }
6739 
6740             // Notify DexManager that the package was installed for new users.
6741             // The updated users should already be indexed and the package code paths
6742             // should not change.
6743             // Don't notify the manager for ephemeral apps as they are not expected to
6744             // survive long enough to benefit of background optimizations.
6745             for (int userId : firstUserIds) {
6746                 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
6747                 // There's a race currently where some install events may interleave with an
6748                 // uninstall. This can lead to package info being null (b/36642664).
6749                 if (info != null) {
6750                     mDexManager.notifyPackageInstalled(info, userId);
6751                 }
6752             }
6753         }
6754 
6755         final boolean deferInstallObserver = succeeded && update && !killApp;
6756         if (deferInstallObserver) {
6757             scheduleDeferredNoKillInstallObserver(res, installObserver);
6758         } else {
6759             notifyInstallObserver(res, installObserver);
6760         }
6761     }
6762 
6763     @Override
notifyPackagesReplacedReceived(String[] packages)6764     public void notifyPackagesReplacedReceived(String[] packages) {
6765         final int callingUid = Binder.getCallingUid();
6766         final int callingUserId = UserHandle.getUserId(callingUid);
6767 
6768         for (String packageName : packages) {
6769             final boolean filterApp;
6770             synchronized (mLock) {
6771                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
6772                 filterApp = shouldFilterApplicationLocked(ps, callingUid, callingUserId);
6773             }
6774             if (!filterApp) {
6775                 notifyInstallObserver(packageName);
6776             }
6777         }
6778     }
6779 
notifyInstallObserver(String packageName)6780     private void notifyInstallObserver(String packageName) {
6781         Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
6782                 mNoKillInstallObservers.remove(packageName);
6783 
6784         if (pair != null) {
6785             notifyInstallObserver(pair.first, pair.second);
6786         }
6787     }
6788 
notifyInstallObserver(PackageInstalledInfo info, IPackageInstallObserver2 installObserver)6789     private void notifyInstallObserver(PackageInstalledInfo info,
6790             IPackageInstallObserver2 installObserver) {
6791         if (installObserver != null) {
6792             try {
6793                 Bundle extras = extrasForInstallResult(info);
6794                 installObserver.onPackageInstalled(info.name, info.returnCode,
6795                         info.returnMsg, extras);
6796             } catch (RemoteException e) {
6797                 Slog.i(TAG, "Observer no longer exists.");
6798             }
6799         }
6800     }
6801 
scheduleDeferredNoKillPostDelete(InstallArgs args)6802     private void scheduleDeferredNoKillPostDelete(InstallArgs args) {
6803         Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_POST_DELETE, args);
6804         mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_POST_DELETE_DELAY_MS);
6805     }
6806 
scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info, IPackageInstallObserver2 observer)6807     private void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
6808             IPackageInstallObserver2 observer) {
6809         String packageName = info.pkg.getPackageName();
6810         mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
6811         Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
6812         mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
6813     }
6814 
6815     @Override
requestChecksums(@onNull String packageName, boolean includeSplits, @Checksum.TypeMask int optional, @Checksum.TypeMask int required, @Nullable List trustedInstallers, @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId)6816     public void requestChecksums(@NonNull String packageName, boolean includeSplits,
6817             @Checksum.TypeMask int optional,
6818             @Checksum.TypeMask int required, @Nullable List trustedInstallers,
6819             @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId) {
6820         requestChecksumsInternal(packageName, includeSplits, optional, required, trustedInstallers,
6821                 onChecksumsReadyListener, userId, mInjector.getBackgroundExecutor(),
6822                 mInjector.getBackgroundHandler());
6823     }
6824 
requestChecksumsInternal(@onNull String packageName, boolean includeSplits, @Checksum.TypeMask int optional, @Checksum.TypeMask int required, @Nullable List trustedInstallers, @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId, @NonNull Executor executor, @NonNull Handler handler)6825     private void requestChecksumsInternal(@NonNull String packageName, boolean includeSplits,
6826             @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
6827             @Nullable List trustedInstallers,
6828             @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
6829             @NonNull Executor executor, @NonNull Handler handler) {
6830         Objects.requireNonNull(packageName);
6831         Objects.requireNonNull(onChecksumsReadyListener);
6832         Objects.requireNonNull(executor);
6833         Objects.requireNonNull(handler);
6834 
6835         final ApplicationInfo applicationInfo = getApplicationInfoInternal(packageName, 0,
6836                 Binder.getCallingUid(), userId);
6837         if (applicationInfo == null) {
6838             throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
6839         }
6840         final InstallSourceInfo installSourceInfo = getInstallSourceInfo(packageName);
6841         final String installerPackageName =
6842                 installSourceInfo != null ? installSourceInfo.getInitiatingPackageName() : null;
6843 
6844         List<Pair<String, File>> filesToChecksum = new ArrayList<>();
6845 
6846         // Adding base split.
6847         filesToChecksum.add(Pair.create(null, new File(applicationInfo.sourceDir)));
6848 
6849         // Adding other splits.
6850         if (includeSplits && applicationInfo.splitNames != null) {
6851             for (int i = 0, size = applicationInfo.splitNames.length; i < size; ++i) {
6852                 filesToChecksum.add(Pair.create(applicationInfo.splitNames[i],
6853                         new File(applicationInfo.splitSourceDirs[i])));
6854             }
6855         }
6856 
6857         final Certificate[] trustedCerts = (trustedInstallers != null) ? decodeCertificates(
6858                 trustedInstallers) : null;
6859 
6860         executor.execute(() -> {
6861             ApkChecksums.Injector injector = new ApkChecksums.Injector(
6862                     () -> mContext,
6863                     () -> handler,
6864                     () -> mInjector.getIncrementalManager(),
6865                     () -> mPmInternal);
6866             ApkChecksums.getChecksums(filesToChecksum, optional, required, installerPackageName,
6867                     trustedCerts, onChecksumsReadyListener, injector);
6868         });
6869     }
6870 
decodeCertificates(@onNull List certs)6871     private static @NonNull Certificate[] decodeCertificates(@NonNull List certs) {
6872         try {
6873             final CertificateFactory cf = CertificateFactory.getInstance("X.509");
6874             final Certificate[] result = new Certificate[certs.size()];
6875             for (int i = 0, size = certs.size(); i < size; ++i) {
6876                 final InputStream is = new ByteArrayInputStream((byte[]) certs.get(i));
6877                 final X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
6878                 result[i] = cert;
6879             }
6880             return result;
6881         } catch (CertificateException e) {
6882             throw ExceptionUtils.propagate(e);
6883         }
6884     }
6885 
6886     /**
6887      * Gets the type of the external storage a package is installed on.
6888      * @param packageVolume The storage volume of the package.
6889      * @param packageIsExternal true if the package is currently installed on
6890      * external/removable/unprotected storage.
6891      * @return {@link StorageEnums#UNKNOWN} if the package is not stored externally or the
6892      * corresponding {@link StorageEnums} storage type value if it is.
6893      * corresponding {@link StorageEnums} storage type value if it is.
6894      */
getPackageExternalStorageType(VolumeInfo packageVolume, boolean packageIsExternal)6895     private static int getPackageExternalStorageType(VolumeInfo packageVolume,
6896             boolean packageIsExternal) {
6897         if (packageVolume != null) {
6898             DiskInfo disk = packageVolume.getDisk();
6899             if (disk != null) {
6900                 if (disk.isSd()) {
6901                     return StorageEnums.SD_CARD;
6902                 }
6903                 if (disk.isUsb()) {
6904                     return StorageEnums.USB;
6905                 }
6906                 if (packageIsExternal) {
6907                     return StorageEnums.OTHER;
6908                 }
6909             }
6910         }
6911         return StorageEnums.UNKNOWN;
6912     }
6913 
6914     private StorageEventListener mStorageListener = new StorageEventListener() {
6915         @Override
6916         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
6917             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
6918                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
6919                     final String volumeUuid = vol.getFsUuid();
6920 
6921                     // Clean up any users or apps that were removed or recreated
6922                     // while this volume was missing
6923                     mUserManager.reconcileUsers(volumeUuid);
6924                     reconcileApps(volumeUuid);
6925 
6926                     // Clean up any install sessions that expired or were
6927                     // cancelled while this volume was missing
6928                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
6929 
6930                     loadPrivatePackages(vol);
6931 
6932                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
6933                     unloadPrivatePackages(vol);
6934                 }
6935             }
6936         }
6937 
6938         @Override
6939         public void onVolumeForgotten(String fsUuid) {
6940             if (TextUtils.isEmpty(fsUuid)) {
6941                 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
6942                 return;
6943             }
6944 
6945             // Remove any apps installed on the forgotten volume
6946             synchronized (mLock) {
6947                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
6948                 for (PackageSetting ps : packages) {
6949                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
6950                     deletePackageVersioned(new VersionedPackage(ps.name,
6951                             PackageManager.VERSION_CODE_HIGHEST),
6952                             new LegacyPackageDeleteObserver(null).getBinder(),
6953                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
6954                     // Try very hard to release any references to this package
6955                     // so we don't risk the system server being killed due to
6956                     // open FDs
6957                     AttributeCache.instance().removePackage(ps.name);
6958                 }
6959 
6960                 mSettings.onVolumeForgotten(fsUuid);
6961                 writeSettingsLPrTEMP();
6962             }
6963         }
6964     };
6965 
extrasForInstallResult(PackageInstalledInfo res)6966     Bundle extrasForInstallResult(PackageInstalledInfo res) {
6967         Bundle extras = null;
6968         switch (res.returnCode) {
6969             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
6970                 extras = new Bundle();
6971                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
6972                         res.origPermission);
6973                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
6974                         res.origPackage);
6975                 break;
6976             }
6977             case PackageManager.INSTALL_SUCCEEDED: {
6978                 extras = new Bundle();
6979                 extras.putBoolean(Intent.EXTRA_REPLACING,
6980                         res.removedInfo != null && res.removedInfo.removedPackage != null);
6981                 break;
6982             }
6983         }
6984         return extras;
6985     }
6986 
scheduleWriteSettingsLocked()6987     void scheduleWriteSettingsLocked() {
6988         // We normally invalidate when we write settings, but in cases where we delay and
6989         // coalesce settings writes, this strategy would have us invalidate the cache too late.
6990         // Invalidating on schedule addresses this problem.
6991         invalidatePackageInfoCache();
6992         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
6993             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
6994         }
6995     }
6996 
scheduleWritePackageListLocked(int userId)6997     void scheduleWritePackageListLocked(int userId) {
6998         invalidatePackageInfoCache();
6999         if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
7000             Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
7001             msg.arg1 = userId;
7002             mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
7003         }
7004     }
7005 
scheduleWritePackageRestrictionsLocked(UserHandle user)7006     void scheduleWritePackageRestrictionsLocked(UserHandle user) {
7007         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
7008         scheduleWritePackageRestrictionsLocked(userId);
7009     }
7010 
scheduleWritePackageRestrictionsLocked(int userId)7011     void scheduleWritePackageRestrictionsLocked(int userId) {
7012         invalidatePackageInfoCache();
7013         final int[] userIds = (userId == UserHandle.USER_ALL)
7014                 ? mUserManager.getUserIds() : new int[]{userId};
7015         for (int nextUserId : userIds) {
7016             if (!mUserManager.exists(nextUserId)) return;
7017 
7018             mDirtyUsers.add(nextUserId);
7019             if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
7020                 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
7021             }
7022         }
7023     }
7024 
main(Context context, Installer installer, @NonNull DomainVerificationService domainVerificationService, boolean factoryTest, boolean onlyCore)7025     public static PackageManagerService main(Context context, Installer installer,
7026             @NonNull DomainVerificationService domainVerificationService, boolean factoryTest,
7027             boolean onlyCore) {
7028         // Self-check for initial settings.
7029         PackageManagerServiceCompilerMapping.checkProperties();
7030         final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
7031                 Trace.TRACE_TAG_PACKAGE_MANAGER);
7032         t.traceBegin("create package manager");
7033         final PackageManagerTracedLock lock = new PackageManagerTracedLock();
7034         final Object installLock = new Object();
7035         HandlerThread backgroundThread = new HandlerThread("PackageManagerBg");
7036         backgroundThread.start();
7037         Handler backgroundHandler = new Handler(backgroundThread.getLooper());
7038 
7039         Injector injector = new Injector(
7040                 context, lock, installer, installLock, new PackageAbiHelperImpl(),
7041                 backgroundHandler,
7042                 SYSTEM_PARTITIONS,
7043                 (i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock),
7044                 (i, pm) -> PermissionManagerService.create(context,
7045                         i.getSystemConfig().getAvailableFeatures()),
7046                 (i, pm) -> new UserManagerService(context, pm,
7047                         new UserDataPreparer(installer, installLock, context, onlyCore),
7048                         lock),
7049                 (i, pm) -> new Settings(Environment.getDataDirectory(),
7050                         RuntimePermissionsPersistence.createInstance(),
7051                         i.getPermissionManagerServiceInternal(),
7052                         domainVerificationService, lock),
7053                 (i, pm) -> AppsFilter.create(pm.mPmInternal, i),
7054                 (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
7055                 (i, pm) -> SystemConfig.getInstance(),
7056                 (i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
7057                         i.getContext(), "*dexopt*"),
7058                 (i, pm) -> new DexManager(i.getContext(), pm, i.getPackageDexOptimizer(),
7059                         i.getInstaller(), i.getInstallLock()),
7060                 (i, pm) -> new ArtManagerService(i.getContext(), pm, i.getInstaller(),
7061                         i.getInstallLock()),
7062                 (i, pm) -> ApexManager.getInstance(),
7063                 (i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()),
7064                 (i, pm) -> (IncrementalManager)
7065                         i.getContext().getSystemService(Context.INCREMENTAL_SERVICE),
7066                 (i, pm) -> new DefaultAppProvider(() -> context.getSystemService(RoleManager.class),
7067                         () -> LocalServices.getService(UserManagerInternal.class)),
7068                 (i, pm) -> new DisplayMetrics(),
7069                 (i, pm) -> new PackageParser2(pm.mSeparateProcesses, pm.mOnlyCore,
7070                         i.getDisplayMetrics(), pm.mCacheDir,
7071                         pm.mPackageParserCallback) /* scanningCachingPackageParserProducer */,
7072                 (i, pm) -> new PackageParser2(pm.mSeparateProcesses, pm.mOnlyCore,
7073                         i.getDisplayMetrics(), null,
7074                         pm.mPackageParserCallback) /* scanningPackageParserProducer */,
7075                 (i, pm) -> new PackageParser2(pm.mSeparateProcesses, false, i.getDisplayMetrics(),
7076                         null, pm.mPackageParserCallback) /* preparingPackageParserProducer */,
7077                 // Prepare a supplier of package parser for the staging manager to parse apex file
7078                 // during the staging installation.
7079                 (i, pm) -> new PackageInstallerService(
7080                         i.getContext(), pm, i::getScanningPackageParser),
7081                 (i, pm, cn) -> new InstantAppResolverConnection(
7082                         i.getContext(), cn, Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE),
7083                 (i, pm) -> new ModuleInfoProvider(i.getContext(), pm),
7084                 (i, pm) -> LegacyPermissionManagerService.create(i.getContext()),
7085                 (i, pm) -> domainVerificationService,
7086                 (i, pm) -> {
7087                     HandlerThread thread = new ServiceThread(TAG,
7088                             Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
7089                     thread.start();
7090                     return pm.new PackageHandler(thread.getLooper());
7091                 },
7092                 new DefaultSystemWrapper(),
7093                 LocalServices::getService,
7094                 context::getSystemService);
7095 
7096 
7097         if (Build.VERSION.SDK_INT <= 0) {
7098             Slog.w(TAG, "**** ro.build.version.sdk not set!");
7099         }
7100 
7101         PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
7102                 Build.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG, Build.VERSION.SDK_INT,
7103                 Build.VERSION.INCREMENTAL);
7104         t.traceEnd(); // "create package manager"
7105 
7106         final CompatChange.ChangeListener selinuxChangeListener = packageName -> {
7107             synchronized (m.mInstallLock) {
7108                 final AndroidPackage pkg;
7109                 final PackageSetting ps;
7110                 final SharedUserSetting sharedUser;
7111                 final String oldSeInfo;
7112                 synchronized (m.mLock) {
7113                     ps = m.mSettings.getPackageLPr(packageName);
7114                     if (ps == null) {
7115                         Slog.e(TAG, "Failed to find package setting " + packageName);
7116                         return;
7117                     }
7118                     pkg = ps.pkg;
7119                     sharedUser = ps.getSharedUser();
7120                     oldSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
7121                 }
7122 
7123                 if (pkg == null) {
7124                     Slog.e(TAG, "Failed to find package " + packageName);
7125                     return;
7126                 }
7127                 final String newSeInfo = SELinuxMMAC.getSeInfo(pkg, sharedUser,
7128                         m.mInjector.getCompatibility());
7129 
7130                 if (!newSeInfo.equals(oldSeInfo)) {
7131                     Slog.i(TAG, "Updating seInfo for package " + packageName + " from: "
7132                             + oldSeInfo + " to: " + newSeInfo);
7133                     ps.getPkgState().setOverrideSeInfo(newSeInfo);
7134                     m.prepareAppDataAfterInstallLIF(pkg);
7135                 }
7136             }
7137         };
7138 
7139         injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,
7140                 selinuxChangeListener);
7141         injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_R_CHANGES,
7142                 selinuxChangeListener);
7143 
7144         m.installWhitelistedSystemPackages();
7145         ServiceManager.addService("package", m);
7146         final PackageManagerNative pmn = m.new PackageManagerNative();
7147         ServiceManager.addService("package_native", pmn);
7148         return m;
7149     }
7150 
7151     /** Install/uninstall system packages for all users based on their user-type, as applicable. */
installWhitelistedSystemPackages()7152     private void installWhitelistedSystemPackages() {
7153         synchronized (mLock) {
7154             final boolean scheduleWrite = mUserManager.installWhitelistedSystemPackages(
7155                     isFirstBoot(), isDeviceUpgrading(), mExistingPackages);
7156             if (scheduleWrite) {
7157                 scheduleWritePackageRestrictionsLocked(UserHandle.USER_ALL);
7158                 scheduleWriteSettingsLocked();
7159             }
7160         }
7161     }
7162 
7163     /**
7164      * Requests that files preopted on a secondary system partition be copied to the data partition
7165      * if possible.  Note that the actual copying of the files is accomplished by init for security
7166      * reasons. This simply requests that the copy takes place and awaits confirmation of its
7167      * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
7168      */
requestCopyPreoptedFiles(Injector injector)7169     private static void requestCopyPreoptedFiles(Injector injector) {
7170         final int WAIT_TIME_MS = 100;
7171         final String CP_PREOPT_PROPERTY = "sys.cppreopt";
7172         if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
7173             SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
7174             // We will wait for up to 100 seconds.
7175             final long timeStart = SystemClock.uptimeMillis();
7176             final long timeEnd = timeStart + 100 * 1000;
7177             long timeNow = timeStart;
7178             while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
7179                 try {
7180                     Thread.sleep(WAIT_TIME_MS);
7181                 } catch (InterruptedException e) {
7182                     // Do nothing
7183                 }
7184                 timeNow = SystemClock.uptimeMillis();
7185                 if (timeNow > timeEnd) {
7186                     SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
7187                     Slog.wtf(TAG, "cppreopt did not finish!");
7188                     break;
7189                 }
7190             }
7191 
7192             Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
7193         }
7194     }
7195 
7196     @VisibleForTesting
7197     public static class ScanPartition extends SystemPartition {
7198         @ScanFlags
7199         public final int scanFlag;
7200 
ScanPartition(@onNull SystemPartition partition)7201         public ScanPartition(@NonNull SystemPartition partition) {
7202             super(partition);
7203             scanFlag = scanFlagForPartition(partition);
7204         }
7205 
7206         /**
7207          * Creates a partition containing the same folders as the original partition but with a
7208          * different root folder. The new partition will include the scan flags of the original
7209          * partition along with any specified additional scan flags.
7210          */
ScanPartition(@onNull File folder, @NonNull ScanPartition original, @ScanFlags int additionalScanFlag)7211         public ScanPartition(@NonNull File folder, @NonNull ScanPartition original,
7212                 @ScanFlags int additionalScanFlag) {
7213             super(folder, original);
7214             this.scanFlag = original.scanFlag | additionalScanFlag;
7215         }
7216 
scanFlagForPartition(PackagePartitions.SystemPartition partition)7217         private static int scanFlagForPartition(PackagePartitions.SystemPartition partition) {
7218             switch (partition.type) {
7219                 case PackagePartitions.PARTITION_SYSTEM:
7220                     return 0;
7221                 case PackagePartitions.PARTITION_VENDOR:
7222                     return SCAN_AS_VENDOR;
7223                 case PackagePartitions.PARTITION_ODM:
7224                     return SCAN_AS_ODM;
7225                 case PackagePartitions.PARTITION_OEM:
7226                     return SCAN_AS_OEM;
7227                 case PackagePartitions.PARTITION_PRODUCT:
7228                     return SCAN_AS_PRODUCT;
7229                 case PackagePartitions.PARTITION_SYSTEM_EXT:
7230                     return SCAN_AS_SYSTEM_EXT;
7231                 default:
7232                     throw new IllegalStateException("Unable to determine scan flag for "
7233                             + partition.getFolder());
7234             }
7235         }
7236 
7237         @Override
toString()7238         public String toString() {
7239             return getFolder().getAbsolutePath() + ":" + scanFlag;
7240         }
7241     }
7242 
7243     // Link watchables to the class
registerObserver()7244     private void registerObserver() {
7245         mPackages.registerObserver(mWatcher);
7246         mSharedLibraries.registerObserver(mWatcher);
7247         mStaticLibsByDeclaringPackage.registerObserver(mWatcher);
7248         mInstrumentation.registerObserver(mWatcher);
7249         mWebInstantAppsDisabled.registerObserver(mWatcher);
7250         mAppsFilter.registerObserver(mWatcher);
7251         mInstantAppRegistry.registerObserver(mWatcher);
7252         mSettings.registerObserver(mWatcher);
7253         mIsolatedOwners.registerObserver(mWatcher);
7254         mComponentResolver.registerObserver(mWatcher);
7255         // If neither "build" attribute is true then this may be a mockito test, and verification
7256         // can fail as a false positive.
7257         Watchable.verifyWatchedAttributes(this, mWatcher, !(mIsEngBuild || mIsUserDebugBuild));
7258     }
7259 
7260     /**
7261      * A extremely minimal constructor designed to start up a PackageManagerService instance for
7262      * testing.
7263      *
7264      * It is assumed that all methods under test will mock the internal fields and thus
7265      * none of the initialization is needed.
7266      */
7267     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
PackageManagerService(@onNull Injector injector, @NonNull TestParams testParams)7268     public PackageManagerService(@NonNull Injector injector, @NonNull TestParams testParams) {
7269         mInjector = injector;
7270         mInjector.bootstrap(this);
7271         mAppsFilter = injector.getAppsFilter();
7272         mComponentResolver = injector.getComponentResolver();
7273         mContext = injector.getContext();
7274         mInstaller = injector.getInstaller();
7275         mInstallLock = injector.getInstallLock();
7276         mLock = injector.getLock();
7277         mPermissionManager = injector.getPermissionManagerServiceInternal();
7278         mSettings = injector.getSettings();
7279         mUserManager = injector.getUserManagerService();
7280         mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
7281         mHandler = injector.getHandler();
7282 
7283         mApexManager = testParams.apexManager;
7284         mArtManagerService = testParams.artManagerService;
7285         mAvailableFeatures = testParams.availableFeatures;
7286         mDefParseFlags = testParams.defParseFlags;
7287         mDefaultAppProvider = testParams.defaultAppProvider;
7288         mLegacyPermissionManager = testParams.legacyPermissionManagerInternal;
7289         mDexManager = testParams.dexManager;
7290         mDirsToScanAsSystem = testParams.dirsToScanAsSystem;
7291         mFactoryTest = testParams.factoryTest;
7292         mIncrementalManager = testParams.incrementalManager;
7293         mInstallerService = testParams.installerService;
7294         mInstantAppRegistry = testParams.instantAppRegistry;
7295         mInstantAppResolverConnection = testParams.instantAppResolverConnection;
7296         mInstantAppResolverSettingsComponent = testParams.instantAppResolverSettingsComponent;
7297         mIsPreNMR1Upgrade = testParams.isPreNmr1Upgrade;
7298         mIsPreNUpgrade = testParams.isPreNupgrade;
7299         mIsPreQUpgrade = testParams.isPreQupgrade;
7300         mIsUpgrade = testParams.isUpgrade;
7301         mMetrics = testParams.Metrics;
7302         mModuleInfoProvider = testParams.moduleInfoProvider;
7303         mMoveCallbacks = testParams.moveCallbacks;
7304         mOnlyCore = testParams.onlyCore;
7305         mOverlayConfig = testParams.overlayConfig;
7306         mPackageDexOptimizer = testParams.packageDexOptimizer;
7307         mPackageParserCallback = testParams.packageParserCallback;
7308         mPendingBroadcasts = testParams.pendingPackageBroadcasts;
7309         mPmInternal = testParams.pmInternal;
7310         mTestUtilityService = testParams.testUtilityService;
7311         mProcessLoggingHandler = testParams.processLoggingHandler;
7312         mProtectedPackages = testParams.protectedPackages;
7313         mSeparateProcesses = testParams.separateProcesses;
7314         mViewCompiler = testParams.viewCompiler;
7315         mRequiredVerifierPackage = testParams.requiredVerifierPackage;
7316         mRequiredInstallerPackage = testParams.requiredInstallerPackage;
7317         mRequiredUninstallerPackage = testParams.requiredUninstallerPackage;
7318         mRequiredPermissionControllerPackage = testParams.requiredPermissionControllerPackage;
7319         mSetupWizardPackage = testParams.setupWizardPackage;
7320         mStorageManagerPackage = testParams.storageManagerPackage;
7321         mDefaultTextClassifierPackage = testParams.defaultTextClassifierPackage;
7322         mSystemTextClassifierPackageName = testParams.systemTextClassifierPackage;
7323         mRetailDemoPackage = testParams.retailDemoPackage;
7324         mRecentsPackage = testParams.recentsPackage;
7325         mDocumenterPackage = testParams.documenterPackage;
7326         mConfiguratorPackage = testParams.configuratorPackage;
7327         mAppPredictionServicePackage = testParams.appPredictionServicePackage;
7328         mIncidentReportApproverPackage = testParams.incidentReportApproverPackage;
7329         mServicesExtensionPackageName = testParams.servicesExtensionPackageName;
7330         mSharedSystemSharedLibraryPackageName = testParams.sharedSystemSharedLibraryPackageName;
7331         mOverlayConfigSignaturePackage = testParams.overlayConfigSignaturePackage;
7332         mResolveComponentName = testParams.resolveComponentName;
7333 
7334         // Disable snapshots in this instance of PackageManagerService, which is only used
7335         // for testing.  The instance still needs a live computer.  The snapshot computer
7336         // is set to null since it must never be used by this instance.
7337         mSnapshotEnabled = false;
7338         mLiveComputer = createLiveComputer();
7339         mSnapshotComputer = null;
7340         mSnapshotStatistics = null;
7341 
7342         mPackages.putAll(testParams.packages);
7343         mEnableFreeCacheV2 = testParams.enableFreeCacheV2;
7344         mSdkVersion = testParams.sdkVersion;
7345         mSystemWrapper = testParams.systemWrapper;
7346         mAppInstallDir = testParams.appInstallDir;
7347         mAppLib32InstallDir = testParams.appLib32InstallDir;
7348         mIsEngBuild = testParams.isEngBuild;
7349         mIsUserDebugBuild = testParams.isUserDebugBuild;
7350         mIncrementalVersion = testParams.incrementalVersion;
7351 
7352         invalidatePackageInfoCache();
7353     }
7354 
PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest, final String buildFingerprint, final boolean isEngBuild, final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion)7355     public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
7356             final String buildFingerprint, final boolean isEngBuild,
7357             final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
7358         mIsEngBuild = isEngBuild;
7359         mIsUserDebugBuild = isUserDebugBuild;
7360         mSdkVersion = sdkVersion;
7361         mIncrementalVersion = incrementalVersion;
7362         mInjector = injector;
7363         mInjector.getSystemWrapper().disablePackageCaches();
7364 
7365         final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
7366                 Trace.TRACE_TAG_PACKAGE_MANAGER);
7367         mPendingBroadcasts = new PendingPackageBroadcasts();
7368 
7369         mInjector.bootstrap(this);
7370         mLock = injector.getLock();
7371         mInstallLock = injector.getInstallLock();
7372         LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
7373         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
7374                 SystemClock.uptimeMillis());
7375         mSystemWrapper = injector.getSystemWrapper();
7376 
7377         mContext = injector.getContext();
7378         mFactoryTest = factoryTest;
7379         mOnlyCore = onlyCore;
7380         mMetrics = injector.getDisplayMetrics();
7381         mInstaller = injector.getInstaller();
7382         mEnableFreeCacheV2 = SystemProperties.getBoolean("fw.free_cache_v2", true);
7383 
7384         // Create sub-components that provide services / data. Order here is important.
7385         t.traceBegin("createSubComponents");
7386 
7387         // Expose private service for system components to use.
7388         mPmInternal = new PackageManagerInternalImpl();
7389         LocalServices.addService(TestUtilityService.class, this);
7390         mTestUtilityService = LocalServices.getService(TestUtilityService.class);
7391         LocalServices.addService(PackageManagerInternal.class, mPmInternal);
7392         mUserManager = injector.getUserManagerService();
7393         mComponentResolver = injector.getComponentResolver();
7394         mPermissionManager = injector.getPermissionManagerServiceInternal();
7395         mSettings = injector.getSettings();
7396         mIncrementalManager = mInjector.getIncrementalManager();
7397         mDefaultAppProvider = mInjector.getDefaultAppProvider();
7398         mLegacyPermissionManager = mInjector.getLegacyPermissionManagerInternal();
7399         PlatformCompat platformCompat = mInjector.getCompatibility();
7400         mPackageParserCallback = new PackageParser2.Callback() {
7401             @Override
7402             public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) {
7403                 return platformCompat.isChangeEnabled(changeId, appInfo);
7404             }
7405 
7406             @Override
7407             public boolean hasFeature(String feature) {
7408                 return PackageManagerService.this.hasSystemFeature(feature, 0);
7409             }
7410         };
7411 
7412         // CHECKSTYLE:ON IndentationCheck
7413         t.traceEnd();
7414 
7415         t.traceBegin("addSharedUsers");
7416         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
7417                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7418         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
7419                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7420         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
7421                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7422         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
7423                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7424         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
7425                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7426         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
7427                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7428         mSettings.addSharedUserLPw("android.uid.se", SE_UID,
7429                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7430         mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
7431                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7432         mSettings.addSharedUserLPw("android.uid.uwb", UWB_UID,
7433                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7434         t.traceEnd();
7435 
7436         String separateProcesses = SystemProperties.get("debug.separate_processes");
7437 
7438         if (separateProcesses != null && separateProcesses.length() > 0) {
7439             if ("*".equals(separateProcesses)) {
7440                 mDefParseFlags = ParsingPackageUtils.PARSE_IGNORE_PROCESSES;
7441                 mSeparateProcesses = null;
7442                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
7443             } else {
7444                 mDefParseFlags = 0;
7445                 mSeparateProcesses = separateProcesses.split(",");
7446                 Slog.w(TAG, "Running with debug.separate_processes: "
7447                         + separateProcesses);
7448             }
7449         } else {
7450             mDefParseFlags = 0;
7451             mSeparateProcesses = null;
7452         }
7453 
7454         mPackageDexOptimizer = injector.getPackageDexOptimizer();
7455         mDexManager = injector.getDexManager();
7456         mArtManagerService = injector.getArtManagerService();
7457         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
7458         mViewCompiler = injector.getViewCompiler();
7459 
7460         mContext.getSystemService(DisplayManager.class)
7461                 .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);
7462 
7463         t.traceBegin("get system config");
7464         SystemConfig systemConfig = injector.getSystemConfig();
7465         mAvailableFeatures = systemConfig.getAvailableFeatures();
7466         t.traceEnd();
7467 
7468         mProtectedPackages = new ProtectedPackages(mContext);
7469 
7470         mApexManager = injector.getApexManager();
7471         mAppsFilter = mInjector.getAppsFilter();
7472 
7473         final List<ScanPartition> scanPartitions = new ArrayList<>();
7474         final List<ApexManager.ActiveApexInfo> activeApexInfos = mApexManager.getActiveApexInfos();
7475         for (int i = 0; i < activeApexInfos.size(); i++) {
7476             final ScanPartition scanPartition = resolveApexToScanPartition(activeApexInfos.get(i));
7477             if (scanPartition != null) {
7478                 scanPartitions.add(scanPartition);
7479             }
7480         }
7481 
7482         mInstantAppRegistry = new InstantAppRegistry(this, mPermissionManager);
7483 
7484         mDirsToScanAsSystem = new ArrayList<>();
7485         mDirsToScanAsSystem.addAll(injector.getSystemPartitions());
7486         mDirsToScanAsSystem.addAll(scanPartitions);
7487         Slog.d(TAG, "Directories scanned as system partitions: " + mDirsToScanAsSystem);
7488 
7489         mAppInstallDir = new File(Environment.getDataDirectory(), "app");
7490         mAppLib32InstallDir = getAppLib32InstallDir();
7491 
7492         mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
7493         mDomainVerificationManager.setConnection(mDomainVerificationConnection);
7494 
7495         synchronized (mLock) {
7496             // Create the computer as soon as the state objects have been installed.  The
7497             // cached computer is the same as the live computer until the end of the
7498             // constructor, at which time the invalidation method updates it.  The cache is
7499             // corked initially to ensure a cached computer is not built until the end of the
7500             // constructor.
7501             mSnapshotStatistics = new SnapshotStatistics();
7502             sSnapshotConsumer = this;
7503             sSnapshotCorked.set(1);
7504             sSnapshotInvalid.set(true);
7505             mLiveComputer = createLiveComputer();
7506             mSnapshotComputer = null;
7507             mSnapshotEnabled = SNAPSHOT_ENABLED;
7508             registerObserver();
7509         }
7510 
7511         // CHECKSTYLE:OFF IndentationCheck
7512         synchronized (mInstallLock) {
7513         // writer
7514         synchronized (mLock) {
7515             mHandler = injector.getHandler();
7516             mProcessLoggingHandler = new ProcessLoggingHandler();
7517             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
7518 
7519             ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
7520                     = systemConfig.getSharedLibraries();
7521             final int builtInLibCount = libConfig.size();
7522             for (int i = 0; i < builtInLibCount; i++) {
7523                 addBuiltInSharedLibraryLocked(libConfig.valueAt(i));
7524             }
7525 
7526             // Now that we have added all the libraries, iterate again to add dependency
7527             // information IFF their dependencies are added.
7528             long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
7529             for (int i = 0; i < builtInLibCount; i++) {
7530                 String name = libConfig.keyAt(i);
7531                 SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
7532                 final int dependencyCount = entry.dependencies.length;
7533                 for (int j = 0; j < dependencyCount; j++) {
7534                     final SharedLibraryInfo dependency =
7535                         getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
7536                     if (dependency != null) {
7537                         getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
7538                     }
7539                 }
7540             }
7541 
7542             SELinuxMMAC.readInstallPolicy();
7543 
7544             t.traceBegin("loadFallbacks");
7545             FallbackCategoryProvider.loadFallbacks();
7546             t.traceEnd();
7547 
7548             t.traceBegin("read user settings");
7549             mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(
7550                     /* excludePartial= */ true,
7551                     /* excludeDying= */ false,
7552                     /* excludePreCreated= */ false));
7553             t.traceEnd();
7554 
7555             mPermissionManager.readLegacyPermissionsTEMP(mSettings.mPermissions);
7556             mPermissionManager.readLegacyPermissionStateTEMP();
7557 
7558             if (!mOnlyCore && mFirstBoot) {
7559                 requestCopyPreoptedFiles(mInjector);
7560             }
7561 
7562             String customResolverActivityName = Resources.getSystem().getString(
7563                     R.string.config_customResolverActivity);
7564             if (!TextUtils.isEmpty(customResolverActivityName)) {
7565                 mCustomResolverComponentName = ComponentName.unflattenFromString(
7566                         customResolverActivityName);
7567             }
7568 
7569             long startTime = SystemClock.uptimeMillis();
7570 
7571             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
7572                     startTime);
7573 
7574             final String bootClassPath = System.getenv("BOOTCLASSPATH");
7575             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
7576 
7577             if (bootClassPath == null) {
7578                 Slog.w(TAG, "No BOOTCLASSPATH found!");
7579             }
7580 
7581             if (systemServerClassPath == null) {
7582                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
7583             }
7584 
7585             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
7586 
7587             final VersionInfo ver = mSettings.getInternalVersion();
7588             mIsUpgrade =
7589                     !buildFingerprint.equals(ver.fingerprint);
7590             if (mIsUpgrade) {
7591                 PackageManagerServiceUtils.logCriticalInfo(Log.INFO,
7592                         "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
7593             }
7594 
7595             // when upgrading from pre-M, promote system app permissions from install to runtime
7596             mPromoteSystemApps =
7597                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
7598 
7599             // When upgrading from pre-N, we need to handle package extraction like first boot,
7600             // as there is no profiling data available.
7601             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
7602 
7603             mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
7604             mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;
7605 
7606             final WatchedArrayMap<String, PackageSetting> packageSettings =
7607                 mSettings.getPackagesLocked();
7608 
7609             // Save the names of pre-existing packages prior to scanning, so we can determine
7610             // which system packages are completely new due to an upgrade.
7611             if (isDeviceUpgrading()) {
7612                 mExistingPackages = new ArraySet<>(packageSettings.size());
7613                 for (PackageSetting ps : packageSettings.values()) {
7614                     mExistingPackages.add(ps.name);
7615                 }
7616             }
7617 
7618             mCacheDir = preparePackageParserCache(mIsEngBuild);
7619 
7620             // Set flag to monitor and not change apk file paths when
7621             // scanning install directories.
7622             int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
7623 
7624             if (mIsUpgrade || mFirstBoot) {
7625                 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
7626             }
7627 
7628             final int systemParseFlags = mDefParseFlags | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
7629             final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
7630 
7631             PackageParser2 packageParser = injector.getScanningCachingPackageParser();
7632 
7633             ExecutorService executorService = ParallelPackageParser.makeExecutorService();
7634             // Prepare apex package info before scanning APKs, these information are needed when
7635             // scanning apk in apex.
7636             mApexManager.scanApexPackagesTraced(packageParser, executorService);
7637             // Collect vendor/product/system_ext overlay packages. (Do this before scanning
7638             // any apps.)
7639             // For security and version matching reason, only consider overlay packages if they
7640             // reside in the right directory.
7641             for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
7642                 final ScanPartition partition = mDirsToScanAsSystem.get(i);
7643                 if (partition.getOverlayFolder() == null) {
7644                     continue;
7645                 }
7646                 scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags,
7647                         systemScanFlags | partition.scanFlag, 0,
7648                         packageParser, executorService);
7649             }
7650 
7651             scanDirTracedLI(frameworkDir, systemParseFlags,
7652                     systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
7653                     packageParser, executorService);
7654             if (!mPackages.containsKey("android")) {
7655                 throw new IllegalStateException(
7656                         "Failed to load frameworks package; check log for warnings");
7657             }
7658             for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
7659                 final ScanPartition partition = mDirsToScanAsSystem.get(i);
7660                 if (partition.getPrivAppFolder() != null) {
7661                     scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
7662                             systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
7663                             packageParser, executorService);
7664                 }
7665                 scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
7666                         systemScanFlags | partition.scanFlag, 0,
7667                         packageParser, executorService);
7668             }
7669 
7670             // Parse overlay configuration files to set default enable state, mutability, and
7671             // priority of system overlays.
7672             mOverlayConfig = OverlayConfig.initializeSystemInstance(
7673                     consumer -> mPmInternal.forEachPackage(
7674                             pkg -> consumer.accept(pkg, pkg.isSystem())));
7675 
7676             // Prune any system packages that no longer exist.
7677             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
7678             // Stub packages must either be replaced with full versions in the /data
7679             // partition or be disabled.
7680             final List<String> stubSystemApps = new ArrayList<>();
7681             final int[] userIds = mUserManager.getUserIds();
7682             if (!mOnlyCore) {
7683                 // do this first before mucking with mPackages for the "expecting better" case
7684                 final int numPackages = mPackages.size();
7685                 for (int index = 0; index < numPackages; index++) {
7686                     final AndroidPackage pkg = mPackages.valueAt(index);
7687                     if (pkg.isStub()) {
7688                         stubSystemApps.add(pkg.getPackageName());
7689                     }
7690                 }
7691 
7692                 // Iterates PackageSettings in reversed order because the item could be removed
7693                 // during the iteration.
7694                 for (int index = packageSettings.size() - 1; index >= 0; index--) {
7695                     final PackageSetting ps = packageSettings.valueAt(index);
7696 
7697                     /*
7698                      * If this is not a system app, it can't be a
7699                      * disable system app.
7700                      */
7701                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7702                         continue;
7703                     }
7704 
7705                     /*
7706                      * If the package is scanned, it's not erased.
7707                      */
7708                     final AndroidPackage scannedPkg = mPackages.get(ps.name);
7709                     if (scannedPkg != null) {
7710                         /*
7711                          * If the system app is both scanned and in the
7712                          * disabled packages list, then it must have been
7713                          * added via OTA. Remove it from the currently
7714                          * scanned package so the previously user-installed
7715                          * application can be scanned.
7716                          */
7717                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
7718                             logCriticalInfo(Log.WARN,
7719                                     "Expecting better updated system app for " + ps.name
7720                                     + "; removing system app.  Last known"
7721                                     + " codePath=" + ps.getPathString()
7722                                     + ", versionCode=" + ps.versionCode
7723                                     + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
7724                             removePackageLI(scannedPkg, true);
7725                             mExpectingBetter.put(ps.name, ps.getPath());
7726                         }
7727 
7728                         continue;
7729                     }
7730 
7731                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
7732                         logCriticalInfo(Log.WARN, "System package " + ps.name
7733                                 + " no longer exists; it's data will be wiped");
7734                         removePackageDataLIF(ps, userIds, null, 0, false);
7735                     } else {
7736                         // we still have a disabled system package, but, it still might have
7737                         // been removed. check the code path still exists and check there's
7738                         // still a package. the latter can happen if an OTA keeps the same
7739                         // code path, but, changes the package name.
7740                         final PackageSetting disabledPs =
7741                                 mSettings.getDisabledSystemPkgLPr(ps.name);
7742                         if (disabledPs.getPath() == null || !disabledPs.getPath().exists()
7743                                 || disabledPs.pkg == null) {
7744                             possiblyDeletedUpdatedSystemApps.add(ps.name);
7745                         } else {
7746                             // We're expecting that the system app should remain disabled, but add
7747                             // it to expecting better to recover in case the data version cannot
7748                             // be scanned.
7749                             mExpectingBetter.put(disabledPs.name, disabledPs.getPath());
7750                         }
7751                     }
7752                 }
7753             }
7754 
7755             final int cachedSystemApps = PackageCacher.sCachedPackageReadCount.get();
7756 
7757             // Remove any shared userIDs that have no associated packages
7758             mSettings.pruneSharedUsersLPw();
7759             final long systemScanTime = SystemClock.uptimeMillis() - startTime;
7760             final int systemPackagesCount = mPackages.size();
7761             Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
7762                     + " ms, packageCount: " + systemPackagesCount
7763                     + " , timePerPackage: "
7764                     + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
7765                     + " , cached: " + cachedSystemApps);
7766             if (mIsUpgrade && systemPackagesCount > 0) {
7767                 //CHECKSTYLE:OFF IndentationCheck
7768                 FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
7769                     BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME,
7770                     systemScanTime / systemPackagesCount);
7771                 //CHECKSTYLE:ON IndentationCheck
7772             }
7773             if (!mOnlyCore) {
7774                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
7775                         SystemClock.uptimeMillis());
7776                 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
7777                         packageParser, executorService);
7778 
7779             }
7780 
7781             packageParser.close();
7782 
7783             List<Runnable> unfinishedTasks = executorService.shutdownNow();
7784             if (!unfinishedTasks.isEmpty()) {
7785                 throw new IllegalStateException("Not all tasks finished before calling close: "
7786                         + unfinishedTasks);
7787             }
7788 
7789             if (!mOnlyCore) {
7790                 // Remove disable package settings for updated system apps that were
7791                 // removed via an OTA. If the update is no longer present, remove the
7792                 // app completely. Otherwise, revoke their system privileges.
7793                 for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
7794                     final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
7795                     final AndroidPackage pkg = mPackages.get(packageName);
7796                     final String msg;
7797 
7798                     // remove from the disabled system list; do this first so any future
7799                     // scans of this package are performed without this state
7800                     mSettings.removeDisabledSystemPackageLPw(packageName);
7801 
7802                     if (pkg == null) {
7803                         // should have found an update, but, we didn't; remove everything
7804                         msg = "Updated system package " + packageName
7805                                 + " no longer exists; removing its data";
7806                         // Actual deletion of code and data will be handled by later
7807                         // reconciliation step
7808                     } else {
7809                         // found an update; revoke system privileges
7810                         msg = "Updated system package " + packageName
7811                                 + " no longer exists; rescanning package on data";
7812 
7813                         // NOTE: We don't do anything special if a stub is removed from the
7814                         // system image. But, if we were [like removing the uncompressed
7815                         // version from the /data partition], this is where it'd be done.
7816 
7817                         // remove the package from the system and re-scan it without any
7818                         // special privileges
7819                         removePackageLI(pkg, true);
7820                         try {
7821                             final File codePath = new File(pkg.getPath());
7822                             scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
7823                         } catch (PackageManagerException e) {
7824                             Slog.e(TAG, "Failed to parse updated, ex-system package: "
7825                                     + e.getMessage());
7826                         }
7827                     }
7828 
7829                     // one final check. if we still have a package setting [ie. it was
7830                     // previously scanned and known to the system], but, we don't have
7831                     // a package [ie. there was an error scanning it from the /data
7832                     // partition], completely remove the package data.
7833                     final PackageSetting ps = mSettings.getPackageLPr(packageName);
7834                     if (ps != null && mPackages.get(packageName) == null) {
7835                         removePackageDataLIF(ps, userIds, null, 0, false);
7836 
7837                     }
7838                     logCriticalInfo(Log.WARN, msg);
7839                 }
7840 
7841                 /*
7842                  * Make sure all system apps that we expected to appear on
7843                  * the userdata partition actually showed up. If they never
7844                  * appeared, crawl back and revive the system version.
7845                  */
7846                 for (int i = 0; i < mExpectingBetter.size(); i++) {
7847                     final String packageName = mExpectingBetter.keyAt(i);
7848                     if (!mPackages.containsKey(packageName)) {
7849                         final File scanFile = mExpectingBetter.valueAt(i);
7850 
7851                         logCriticalInfo(Log.WARN, "Expected better " + packageName
7852                                 + " but never showed up; reverting to system");
7853 
7854                         @ParseFlags int reparseFlags = 0;
7855                         @ScanFlags int rescanFlags = 0;
7856                         for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) {
7857                             final ScanPartition partition = mDirsToScanAsSystem.get(i1);
7858                             if (partition.containsPrivApp(scanFile)) {
7859                                 reparseFlags = systemParseFlags;
7860                                 rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
7861                                         | partition.scanFlag;
7862                                 break;
7863                             }
7864                             if (partition.containsApp(scanFile)) {
7865                                 reparseFlags = systemParseFlags;
7866                                 rescanFlags = systemScanFlags | partition.scanFlag;
7867                                 break;
7868                             }
7869                         }
7870                         if (rescanFlags == 0) {
7871                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
7872                             continue;
7873                         }
7874                         mSettings.enableSystemPackageLPw(packageName);
7875 
7876                         try {
7877                             final AndroidPackage newPkg = scanPackageTracedLI(
7878                                     scanFile, reparseFlags, rescanFlags, 0, null);
7879                             // We rescanned a stub, add it to the list of stubbed system packages
7880                             if (newPkg.isStub()) {
7881                                 stubSystemApps.add(packageName);
7882                             }
7883                         } catch (PackageManagerException e) {
7884                             Slog.e(TAG, "Failed to parse original system package: "
7885                                     + e.getMessage());
7886                         }
7887                     }
7888                 }
7889 
7890                 // Uncompress and install any stubbed system applications.
7891                 // This must be done last to ensure all stubs are replaced or disabled.
7892                 installSystemStubPackages(stubSystemApps, scanFlags);
7893 
7894                 final int cachedNonSystemApps = PackageCacher.sCachedPackageReadCount.get()
7895                                 - cachedSystemApps;
7896 
7897                 final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
7898                 final int dataPackagesCount = mPackages.size() - systemPackagesCount;
7899                 Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
7900                         + " ms, packageCount: " + dataPackagesCount
7901                         + " , timePerPackage: "
7902                         + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
7903                         + " , cached: " + cachedNonSystemApps);
7904                 if (mIsUpgrade && dataPackagesCount > 0) {
7905                     //CHECKSTYLE:OFF IndentationCheck
7906                     FrameworkStatsLog.write(
7907                         FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
7908                         BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME,
7909                         dataScanTime / dataPackagesCount);
7910                     //CHECKSTYLE:OFF IndentationCheck
7911                 }
7912             }
7913             mExpectingBetter.clear();
7914 
7915             // Resolve the storage manager.
7916             mStorageManagerPackage = getStorageManagerPackageName();
7917 
7918             // Resolve protected action filters. Only the setup wizard is allowed to
7919             // have a high priority filter for these actions.
7920             mSetupWizardPackage = getSetupWizardPackageNameImpl();
7921             mComponentResolver.fixProtectedFilterPriorities();
7922 
7923             mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
7924             mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
7925             mDocumenterPackage = getDocumenterPackageName();
7926             mConfiguratorPackage = getDeviceConfiguratorPackageName();
7927             mAppPredictionServicePackage = getAppPredictionServicePackageName();
7928             mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
7929             mRetailDemoPackage = getRetailDemoPackageName();
7930             mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
7931             mRecentsPackage = getRecentsPackageName();
7932 
7933             // Now that we know all of the shared libraries, update all clients to have
7934             // the correct library paths.
7935             updateAllSharedLibrariesLocked(null, null, Collections.unmodifiableMap(mPackages));
7936 
7937             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
7938                 // NOTE: We ignore potential failures here during a system scan (like
7939                 // the rest of the commands above) because there's precious little we
7940                 // can do about it. A settings error is reported, though.
7941                 final List<String> changedAbiCodePath =
7942                         applyAdjustedAbiToSharedUser(setting, null /*scannedPackage*/,
7943                         mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
7944                                 setting.packages, null /*scannedPackage*/));
7945                 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
7946                     for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
7947                         final String codePathString = changedAbiCodePath.get(i);
7948                         try {
7949                             mInstaller.rmdex(codePathString,
7950                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
7951                         } catch (InstallerException ignored) {
7952                         }
7953                     }
7954                 }
7955                 // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
7956                 // SELinux domain.
7957                 setting.fixSeInfoLocked();
7958                 setting.updateProcesses();
7959             }
7960 
7961             // Now that we know all the packages we are keeping,
7962             // read and update their last usage times.
7963             mPackageUsage.read(packageSettings);
7964             mCompilerStats.read();
7965 
7966             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
7967                     SystemClock.uptimeMillis());
7968             Slog.i(TAG, "Time to scan packages: "
7969                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
7970                     + " seconds");
7971 
7972             // If the build fingerprint has changed since the last time we booted,
7973             // we need to re-grant app permission to catch any new ones that
7974             // appear.  This is really a hack, and means that apps can in some
7975             // cases get permissions that the user didn't initially explicitly
7976             // allow...  it would be nice to have some better way to handle
7977             // this situation.
7978             if (mIsUpgrade) {
7979                 Slog.i(TAG, "Build fingerprint changed from " + ver.fingerprint + " to "
7980                         + Build.FINGERPRINT + "; regranting permissions for internal storage");
7981             }
7982             mPermissionManager.onStorageVolumeMounted(
7983                     StorageManager.UUID_PRIVATE_INTERNAL, mIsUpgrade);
7984             ver.sdkVersion = mSdkVersion;
7985 
7986             // If this is the first boot or an update from pre-M, and it is a normal
7987             // boot, then we need to initialize the default preferred apps across
7988             // all defined users.
7989             if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
7990                 for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
7991                     mSettings.applyDefaultPreferredAppsLPw(user.id);
7992                 }
7993             }
7994 
7995             // Prepare storage for system user really early during boot,
7996             // since core system apps like SettingsProvider and SystemUI
7997             // can't wait for user to start
7998             final int storageFlags;
7999             if (StorageManager.isFileEncryptedNativeOrEmulated()) {
8000                 storageFlags = StorageManager.FLAG_STORAGE_DE;
8001             } else {
8002                 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
8003             }
8004             List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
8005                     UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
8006                     true /* onlyCoreApps */);
8007             mPrepareAppDataFuture = SystemServerInitThreadPool.submit(() -> {
8008                 TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
8009                         Trace.TRACE_TAG_PACKAGE_MANAGER);
8010                 traceLog.traceBegin("AppDataFixup");
8011                 try {
8012                     mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
8013                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
8014                 } catch (InstallerException e) {
8015                     Slog.w(TAG, "Trouble fixing GIDs", e);
8016                 }
8017                 traceLog.traceEnd();
8018 
8019                 traceLog.traceBegin("AppDataPrepare");
8020                 if (deferPackages == null || deferPackages.isEmpty()) {
8021                     return;
8022                 }
8023                 int count = 0;
8024                 final Installer.Batch batch = new Installer.Batch();
8025                 for (String pkgName : deferPackages) {
8026                     AndroidPackage pkg = null;
8027                     synchronized (mLock) {
8028                         PackageSetting ps = mSettings.getPackageLPr(pkgName);
8029                         if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
8030                             pkg = ps.pkg;
8031                         }
8032                     }
8033                     if (pkg != null) {
8034                         prepareAppDataAndMigrate(batch, pkg, UserHandle.USER_SYSTEM, storageFlags,
8035                                 true /* maybeMigrateAppData */);
8036                         count++;
8037                     }
8038                 }
8039                 synchronized (mInstallLock) {
8040                     executeBatchLI(batch);
8041                 }
8042                 traceLog.traceEnd();
8043                 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
8044             }, "prepareAppData");
8045 
8046             // If this is first boot after an OTA, and a normal boot, then
8047             // we need to clear code cache directories.
8048             // Note that we do *not* clear the application profiles. These remain valid
8049             // across OTAs and are used to drive profile verification (post OTA) and
8050             // profile compilation (without waiting to collect a fresh set of profiles).
8051             if (mIsUpgrade && !mOnlyCore) {
8052                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
8053                 for (int i = 0; i < packageSettings.size(); i++) {
8054                     final PackageSetting ps = packageSettings.valueAt(i);
8055                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
8056                         // No apps are running this early, so no need to freeze
8057                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
8058                                 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
8059                                         | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
8060                                         | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
8061                     }
8062                 }
8063                 ver.fingerprint = Build.FINGERPRINT;
8064             }
8065 
8066             // Legacy existing (installed before Q) non-system apps to hide
8067             // their icons in launcher.
8068             if (!mOnlyCore && mIsPreQUpgrade) {
8069                 Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
8070                 int size = packageSettings.size();
8071                 for (int i = 0; i < size; i++) {
8072                     final PackageSetting ps = packageSettings.valueAt(i);
8073                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8074                         continue;
8075                     }
8076                     ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
8077                             UserHandle.USER_SYSTEM);
8078                 }
8079             }
8080 
8081             // clear only after permissions and other defaults have been updated
8082             mPromoteSystemApps = false;
8083 
8084             // All the changes are done during package scanning.
8085             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
8086 
8087             // can downgrade to reader
8088             t.traceBegin("write settings");
8089             writeSettingsLPrTEMP();
8090             t.traceEnd();
8091             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
8092                     SystemClock.uptimeMillis());
8093 
8094             if (!mOnlyCore) {
8095                 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
8096                 mRequiredInstallerPackage = getRequiredInstallerLPr();
8097                 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
8098                 ComponentName intentFilterVerifierComponent =
8099                         getIntentFilterVerifierComponentNameLPr();
8100                 ComponentName domainVerificationAgent =
8101                         getDomainVerificationAgentComponentNameLPr();
8102 
8103                 DomainVerificationProxy domainVerificationProxy = DomainVerificationProxy.makeProxy(
8104                         intentFilterVerifierComponent, domainVerificationAgent, mContext,
8105                         mDomainVerificationManager, mDomainVerificationManager.getCollector(),
8106                         mDomainVerificationConnection);
8107 
8108                 mDomainVerificationManager.setProxy(domainVerificationProxy);
8109 
8110                 mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
8111                 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
8112                         PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
8113                         SharedLibraryInfo.VERSION_UNDEFINED);
8114             } else {
8115                 mRequiredVerifierPackage = null;
8116                 mRequiredInstallerPackage = null;
8117                 mRequiredUninstallerPackage = null;
8118                 mServicesExtensionPackageName = null;
8119                 mSharedSystemSharedLibraryPackageName = null;
8120             }
8121 
8122             // PermissionController hosts default permission granting and role management, so it's a
8123             // critical part of the core system.
8124             mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
8125 
8126             mSettings.setPermissionControllerVersion(
8127                     getPackageInfo(mRequiredPermissionControllerPackage, 0,
8128                             UserHandle.USER_SYSTEM).getLongVersionCode());
8129 
8130             // Initialize InstantAppRegistry's Instant App list for all users.
8131             for (AndroidPackage pkg : mPackages.values()) {
8132                 if (pkg.isSystem()) {
8133                     continue;
8134                 }
8135                 for (int userId : userIds) {
8136                     final PackageSetting ps = getPackageSetting(pkg.getPackageName());
8137                     if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
8138                         continue;
8139                     }
8140                     mInstantAppRegistry.addInstantAppLPw(userId, ps.appId);
8141                 }
8142             }
8143 
8144             mInstallerService = mInjector.getPackageInstallerService();
8145             final ComponentName instantAppResolverComponent = getInstantAppResolverLPr();
8146             if (instantAppResolverComponent != null) {
8147                 if (DEBUG_INSTANT) {
8148                     Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
8149                 }
8150                 mInstantAppResolverConnection =
8151                         mInjector.getInstantAppResolverConnection(instantAppResolverComponent);
8152                 mInstantAppResolverSettingsComponent =
8153                         getInstantAppResolverSettingsLPr(instantAppResolverComponent);
8154             } else {
8155                 mInstantAppResolverConnection = null;
8156                 mInstantAppResolverSettingsComponent = null;
8157             }
8158             updateInstantAppInstallerLocked(null);
8159 
8160             // Read and update the usage of dex files.
8161             // Do this at the end of PM init so that all the packages have their
8162             // data directory reconciled.
8163             // At this point we know the code paths of the packages, so we can validate
8164             // the disk file and build the internal cache.
8165             // The usage file is expected to be small so loading and verifying it
8166             // should take a fairly small time compare to the other activities (e.g. package
8167             // scanning).
8168             final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
8169             for (int userId : userIds) {
8170                 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
8171             }
8172             mDexManager.load(userPackages);
8173             if (mIsUpgrade) {
8174                 FrameworkStatsLog.write(
8175                         FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
8176                         BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME,
8177                         SystemClock.uptimeMillis() - startTime);
8178             }
8179 
8180             // Rebild the live computer since some attributes have been rebuilt.
8181             mLiveComputer = createLiveComputer();
8182 
8183         } // synchronized (mLock)
8184         } // synchronized (mInstallLock)
8185         // CHECKSTYLE:ON IndentationCheck
8186 
8187         mModuleInfoProvider = mInjector.getModuleInfoProvider();
8188         mInjector.getSystemWrapper().enablePackageCaches();
8189 
8190         // Now after opening every single application zip, make sure they
8191         // are all flushed.  Not really needed, but keeps things nice and
8192         // tidy.
8193         t.traceBegin("GC");
8194         VMRuntime.getRuntime().requestConcurrentGC();
8195         t.traceEnd();
8196 
8197         // The initial scanning above does many calls into installd while
8198         // holding the mPackages lock, but we're mostly interested in yelling
8199         // once we have a booted system.
8200         mInstaller.setWarnIfHeld(mLock);
8201 
8202         ParsingPackageUtils.readConfigUseRoundIcon(mContext.getResources());
8203 
8204         mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
8205 
8206         Slog.i(TAG, "Fix for b/169414761 is applied");
8207     }
8208 
8209     /**
8210      * Uncompress and install stub applications.
8211      * <p>In order to save space on the system partition, some applications are shipped in a
8212      * compressed form. In addition the compressed bits for the full application, the
8213      * system image contains a tiny stub comprised of only the Android manifest.
8214      * <p>During the first boot, attempt to uncompress and install the full application. If
8215      * the application can't be installed for any reason, disable the stub and prevent
8216      * uncompressing the full application during future boots.
8217      * <p>In order to forcefully attempt an installation of a full application, go to app
8218      * settings and enable the application.
8219      */
installSystemStubPackages(@onNull List<String> systemStubPackageNames, @ScanFlags int scanFlags)8220     private void installSystemStubPackages(@NonNull List<String> systemStubPackageNames,
8221             @ScanFlags int scanFlags) {
8222         for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
8223             final String packageName = systemStubPackageNames.get(i);
8224             // skip if the system package is already disabled
8225             if (mSettings.isDisabledSystemPackageLPr(packageName)) {
8226                 systemStubPackageNames.remove(i);
8227                 continue;
8228             }
8229             // skip if the package isn't installed (?!); this should never happen
8230             final AndroidPackage pkg = mPackages.get(packageName);
8231             if (pkg == null) {
8232                 systemStubPackageNames.remove(i);
8233                 continue;
8234             }
8235             // skip if the package has been disabled by the user
8236             final PackageSetting ps = mSettings.getPackageLPr(packageName);
8237             if (ps != null) {
8238                 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
8239                 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
8240                     systemStubPackageNames.remove(i);
8241                     continue;
8242                 }
8243             }
8244 
8245             // install the package to replace the stub on /system
8246             try {
8247                 installStubPackageLI(pkg, 0, scanFlags);
8248                 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
8249                         UserHandle.USER_SYSTEM, "android");
8250                 systemStubPackageNames.remove(i);
8251             } catch (PackageManagerException e) {
8252                 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
8253             }
8254 
8255             // any failed attempt to install the package will be cleaned up later
8256         }
8257 
8258         // disable any stub still left; these failed to install the full application
8259         for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
8260             final String pkgName = systemStubPackageNames.get(i);
8261             final PackageSetting ps = mSettings.getPackageLPr(pkgName);
8262             ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
8263                     UserHandle.USER_SYSTEM, "android");
8264             logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
8265         }
8266     }
8267 
8268     /**
8269      * Extract, install and enable a stub package.
8270      * <p>If the compressed file can not be extracted / installed for any reason, the stub
8271      * APK will be installed and the package will be disabled. To recover from this situation,
8272      * the user will need to go into system settings and re-enable the package.
8273      */
enableCompressedPackage(AndroidPackage stubPkg, @NonNull PackageSetting stubPkgSetting)8274     private boolean enableCompressedPackage(AndroidPackage stubPkg,
8275             @NonNull PackageSetting stubPkgSetting) {
8276         final int parseFlags = mDefParseFlags | ParsingPackageUtils.PARSE_CHATTY
8277                 | PackageParser.PARSE_ENFORCE_CODE;
8278         synchronized (mInstallLock) {
8279             final AndroidPackage pkg;
8280             try (PackageFreezer freezer =
8281                     freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
8282                 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
8283                 synchronized (mLock) {
8284                     prepareAppDataAfterInstallLIF(pkg);
8285                     try {
8286                         updateSharedLibrariesLocked(pkg, stubPkgSetting, null, null,
8287                                 Collections.unmodifiableMap(mPackages));
8288                     } catch (PackageManagerException e) {
8289                         Slog.w(TAG, "updateAllSharedLibrariesLPw failed: ", e);
8290                     }
8291                     mPermissionManager.onPackageInstalled(pkg,
8292                             PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
8293                             UserHandle.USER_ALL);
8294                     writeSettingsLPrTEMP();
8295                 }
8296             } catch (PackageManagerException e) {
8297                 // Whoops! Something went very wrong; roll back to the stub and disable the package
8298                 try (PackageFreezer freezer =
8299                         freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
8300                     synchronized (mLock) {
8301                         // NOTE: Ensure the system package is enabled; even for a compressed stub.
8302                         // If we don't, installing the system package fails during scan
8303                         enableSystemPackageLPw(stubPkg);
8304                     }
8305                     installPackageFromSystemLIF(stubPkg.getPath(),
8306                             mUserManager.getUserIds() /*allUserHandles*/, null /*origUserHandles*/,
8307                             true /*writeSettings*/);
8308                 } catch (PackageManagerException pme) {
8309                     // Serious WTF; we have to be able to install the stub
8310                     Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
8311                             pme);
8312                 } finally {
8313                     // Disable the package; the stub by itself is not runnable
8314                     synchronized (mLock) {
8315                         final PackageSetting stubPs = mSettings.getPackageLPr(
8316                                 stubPkg.getPackageName());
8317                         if (stubPs != null) {
8318                             stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED,
8319                                     UserHandle.USER_SYSTEM, "android");
8320                         }
8321                         writeSettingsLPrTEMP();
8322                     }
8323                 }
8324                 return false;
8325             }
8326             clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
8327                     | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
8328             mDexManager.notifyPackageUpdated(pkg.getPackageName(),
8329                     pkg.getBaseApkPath(), pkg.getSplitCodePaths());
8330         }
8331         return true;
8332     }
8333 
installStubPackageLI(AndroidPackage stubPkg, @ParseFlags int parseFlags, @ScanFlags int scanFlags)8334     private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
8335             @ParseFlags int parseFlags, @ScanFlags int scanFlags)
8336                     throws PackageManagerException {
8337         if (DEBUG_COMPRESSION) {
8338             Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName());
8339         }
8340         // uncompress the binary to its eventual destination on /data
8341         final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getPath());
8342         if (scanFile == null) {
8343             throw new PackageManagerException(
8344                     "Unable to decompress stub at " + stubPkg.getPath());
8345         }
8346         synchronized (mLock) {
8347             mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
8348         }
8349         removePackageLI(stubPkg, true /*chatty*/);
8350         try {
8351             return scanPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null);
8352         } catch (PackageManagerException e) {
8353             Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
8354                     e);
8355             // Remove the failed install
8356             removeCodePathLI(scanFile);
8357             throw e;
8358         }
8359     }
8360 
8361     /**
8362      * Decompresses the given package on the system image onto
8363      * the /data partition.
8364      * @return The directory the package was decompressed into. Otherwise, {@code null}.
8365      */
decompressPackage(String packageName, String codePath)8366     private File decompressPackage(String packageName, String codePath) {
8367         final File[] compressedFiles = getCompressedFiles(codePath);
8368         if (compressedFiles == null || compressedFiles.length == 0) {
8369             if (DEBUG_COMPRESSION) {
8370                 Slog.i(TAG, "No files to decompress: " + codePath);
8371             }
8372             return null;
8373         }
8374         final File dstCodePath =
8375                 getNextCodePath(Environment.getDataAppDirectory(null), packageName);
8376         int ret = PackageManager.INSTALL_SUCCEEDED;
8377         try {
8378             makeDirRecursive(dstCodePath, 0755);
8379             for (File srcFile : compressedFiles) {
8380                 final String srcFileName = srcFile.getName();
8381                 final String dstFileName = srcFileName.substring(
8382                         0, srcFileName.length() - COMPRESSED_EXTENSION.length());
8383                 final File dstFile = new File(dstCodePath, dstFileName);
8384                 ret = decompressFile(srcFile, dstFile);
8385                 if (ret != PackageManager.INSTALL_SUCCEEDED) {
8386                     logCriticalInfo(Log.ERROR, "Failed to decompress"
8387                             + "; pkg: " + packageName
8388                             + ", file: " + dstFileName);
8389                     break;
8390                 }
8391             }
8392         } catch (ErrnoException e) {
8393             logCriticalInfo(Log.ERROR, "Failed to decompress"
8394                     + "; pkg: " + packageName
8395                     + ", err: " + e.errno);
8396         }
8397         if (ret == PackageManager.INSTALL_SUCCEEDED) {
8398             final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
8399             NativeLibraryHelper.Handle handle = null;
8400             try {
8401                 handle = NativeLibraryHelper.Handle.create(dstCodePath);
8402                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
8403                         null /*abiOverride*/, false /*isIncremental*/);
8404             } catch (IOException e) {
8405                 logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
8406                         + "; pkg: " + packageName);
8407                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
8408             } finally {
8409                 IoUtils.closeQuietly(handle);
8410             }
8411         }
8412         if (ret == PackageManager.INSTALL_SUCCEEDED) {
8413             // NOTE: During boot, we have to delay releasing cblocks for no other reason than
8414             // we cannot retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}.
8415             // When we no longer need to read that setting, cblock release can occur always
8416             // occur here directly
8417             if (!mSystemReady) {
8418                 if (mReleaseOnSystemReady == null) {
8419                     mReleaseOnSystemReady = new ArrayList<>();
8420                 }
8421                 mReleaseOnSystemReady.add(dstCodePath);
8422             } else {
8423                 final ContentResolver resolver = mContext.getContentResolver();
8424                 F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
8425             }
8426         }
8427         if (ret != PackageManager.INSTALL_SUCCEEDED) {
8428             if (!dstCodePath.exists()) {
8429                 return null;
8430             }
8431             removeCodePathLI(dstCodePath);
8432             return null;
8433         }
8434 
8435         return dstCodePath;
8436     }
8437 
8438     @GuardedBy("mLock")
updateInstantAppInstallerLocked(String modifiedPackage)8439     private void updateInstantAppInstallerLocked(String modifiedPackage) {
8440         // we're only interested in updating the installer appliction when 1) it's not
8441         // already set or 2) the modified package is the installer
8442         if (mInstantAppInstallerActivity != null
8443                 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
8444                         .equals(modifiedPackage)) {
8445             return;
8446         }
8447         setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
8448     }
8449 
preparePackageParserCache(boolean forEngBuild)8450     private @Nullable File preparePackageParserCache(boolean forEngBuild) {
8451         if (!FORCE_PACKAGE_PARSED_CACHE_ENABLED) {
8452             if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
8453                 return null;
8454             }
8455 
8456             // Disable package parsing on eng builds to allow for faster incremental development.
8457             if (forEngBuild) {
8458                 return null;
8459             }
8460 
8461             if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
8462                 Slog.i(TAG, "Disabling package parser cache due to system property.");
8463                 return null;
8464             }
8465         }
8466 
8467         // The base directory for the package parser cache lives under /data/system/.
8468         final File cacheBaseDir = Environment.getPackageCacheDirectory();
8469         if (!FileUtils.createDir(cacheBaseDir)) {
8470             return null;
8471         }
8472 
8473         // There are several items that need to be combined together to safely
8474         // identify cached items. In particular, changing the value of certain
8475         // feature flags should cause us to invalidate any caches.
8476         final String cacheName = FORCE_PACKAGE_PARSED_CACHE_ENABLED ? "debug"
8477                 : SystemProperties.digestOf("ro.build.fingerprint");
8478 
8479         // Reconcile cache directories, keeping only what we'd actually use.
8480         for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) {
8481             if (Objects.equals(cacheName, cacheDir.getName())) {
8482                 Slog.d(TAG, "Keeping known cache " + cacheDir.getName());
8483             } else {
8484                 Slog.d(TAG, "Destroying unknown cache " + cacheDir.getName());
8485                 FileUtils.deleteContentsAndDir(cacheDir);
8486             }
8487         }
8488 
8489         // Return the versioned package cache directory.
8490         File cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
8491 
8492         if (cacheDir == null) {
8493             // Something went wrong. Attempt to delete everything and return.
8494             Slog.wtf(TAG, "Cache directory cannot be created - wiping base dir " + cacheBaseDir);
8495             FileUtils.deleteContentsAndDir(cacheBaseDir);
8496             return null;
8497         }
8498 
8499         // The following is a workaround to aid development on non-numbered userdebug
8500         // builds or cases where "adb sync" is used on userdebug builds. If we detect that
8501         // the system partition is newer.
8502         //
8503         // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
8504         // that starts with "eng." to signify that this is an engineering build and not
8505         // destined for release.
8506         if (mIsUserDebugBuild && mIncrementalVersion.startsWith("eng.")) {
8507             Slog.w(TAG, "Wiping cache directory because the system partition changed.");
8508 
8509             // Heuristic: If the /system directory has been modified recently due to an "adb sync"
8510             // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
8511             // in general and should not be used for production changes. In this specific case,
8512             // we know that they will work.
8513             File frameworkDir =
8514                     new File(Environment.getRootDirectory(), "framework");
8515             if (cacheDir.lastModified() < frameworkDir.lastModified()) {
8516                 FileUtils.deleteContents(cacheBaseDir);
8517                 cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
8518             }
8519         }
8520 
8521         return cacheDir;
8522     }
8523 
8524     @Override
isFirstBoot()8525     public boolean isFirstBoot() {
8526         // allow instant applications
8527         return mFirstBoot;
8528     }
8529 
8530     @Override
isOnlyCoreApps()8531     public boolean isOnlyCoreApps() {
8532         // allow instant applications
8533         return mOnlyCore;
8534     }
8535 
8536     @Override
isDeviceUpgrading()8537     public boolean isDeviceUpgrading() {
8538         // allow instant applications
8539         // The system property allows testing ota flow when upgraded to the same image.
8540         return mIsUpgrade || SystemProperties.getBoolean(
8541                 "persist.pm.mock-upgrade", false /* default */);
8542     }
8543 
getRequiredButNotReallyRequiredVerifierLPr()8544     private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
8545         final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
8546 
8547         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
8548                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8549                 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
8550         if (matches.size() == 1) {
8551             return matches.get(0).getComponentInfo().packageName;
8552         } else if (matches.size() == 0) {
8553             Log.w(TAG, "There should probably be a verifier, but, none were found");
8554             return null;
8555         }
8556         throw new RuntimeException("There must be exactly one verifier; found " + matches);
8557     }
8558 
getRequiredSharedLibraryLPr(String name, int version)8559     private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
8560         synchronized (mLock) {
8561             SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(name, version);
8562             if (libraryInfo == null) {
8563                 throw new IllegalStateException("Missing required shared library:" + name);
8564             }
8565             String packageName = libraryInfo.getPackageName();
8566             if (packageName == null) {
8567                 throw new IllegalStateException("Expected a package for shared library " + name);
8568             }
8569             return packageName;
8570         }
8571     }
8572 
8573     @NonNull
getRequiredServicesExtensionPackageLPr()8574     private String getRequiredServicesExtensionPackageLPr() {
8575         String servicesExtensionPackage =
8576                 ensureSystemPackageName(
8577                         mContext.getString(R.string.config_servicesExtensionPackage));
8578         if (TextUtils.isEmpty(servicesExtensionPackage)) {
8579             throw new RuntimeException(
8580                     "Required services extension package is missing, check "
8581                             + "config_servicesExtensionPackage.");
8582         }
8583         return servicesExtensionPackage;
8584     }
8585 
getRequiredInstallerLPr()8586     private @NonNull String getRequiredInstallerLPr() {
8587         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
8588         intent.addCategory(Intent.CATEGORY_DEFAULT);
8589         intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE);
8590 
8591         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
8592                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8593                 UserHandle.USER_SYSTEM);
8594         if (matches.size() == 1) {
8595             ResolveInfo resolveInfo = matches.get(0);
8596             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
8597                 throw new RuntimeException("The installer must be a privileged app");
8598             }
8599             return matches.get(0).getComponentInfo().packageName;
8600         } else {
8601             throw new RuntimeException("There must be exactly one installer; found " + matches);
8602         }
8603     }
8604 
getRequiredUninstallerLPr()8605     private @NonNull String getRequiredUninstallerLPr() {
8606         final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
8607         intent.addCategory(Intent.CATEGORY_DEFAULT);
8608         intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
8609 
8610         final ResolveInfo resolveInfo = resolveIntent(intent, null,
8611                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8612                 UserHandle.USER_SYSTEM);
8613         if (resolveInfo == null ||
8614                 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
8615             throw new RuntimeException("There must be exactly one uninstaller; found "
8616                     + resolveInfo);
8617         }
8618         return resolveInfo.getComponentInfo().packageName;
8619     }
8620 
getRequiredPermissionControllerLPr()8621     private @NonNull String getRequiredPermissionControllerLPr() {
8622         final Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSIONS);
8623         intent.addCategory(Intent.CATEGORY_DEFAULT);
8624 
8625         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
8626                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8627                 UserHandle.USER_SYSTEM);
8628         if (matches.size() == 1) {
8629             ResolveInfo resolveInfo = matches.get(0);
8630             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
8631                 throw new RuntimeException("The permissions manager must be a privileged app");
8632             }
8633             return matches.get(0).getComponentInfo().packageName;
8634         } else {
8635             throw new RuntimeException("There must be exactly one permissions manager; found "
8636                     + matches);
8637         }
8638     }
8639 
getIntentFilterVerifierComponentNameLPr()8640     private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
8641         final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
8642 
8643         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
8644                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8645                 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
8646         ResolveInfo best = null;
8647         final int N = matches.size();
8648         for (int i = 0; i < N; i++) {
8649             final ResolveInfo cur = matches.get(i);
8650             final String packageName = cur.getComponentInfo().packageName;
8651             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
8652                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
8653                 continue;
8654             }
8655 
8656             if (best == null || cur.priority > best.priority) {
8657                 best = cur;
8658             }
8659         }
8660 
8661         if (best != null) {
8662             return best.getComponentInfo().getComponentName();
8663         }
8664         Slog.w(TAG, "Intent filter verifier not found");
8665         return null;
8666     }
8667 
8668     @Nullable
getDomainVerificationAgentComponentNameLPr()8669     private ComponentName getDomainVerificationAgentComponentNameLPr() {
8670         Intent intent = new Intent(Intent.ACTION_DOMAINS_NEED_VERIFICATION);
8671         List<ResolveInfo> matches = queryIntentReceiversInternal(intent, null,
8672                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8673                 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
8674         ResolveInfo best = null;
8675         final int N = matches.size();
8676         for (int i = 0; i < N; i++) {
8677             final ResolveInfo cur = matches.get(i);
8678             final String packageName = cur.getComponentInfo().packageName;
8679             if (checkPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT,
8680                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
8681                 Slog.w(TAG, "Domain verification agent found but does not hold permission: "
8682                         + packageName);
8683                 continue;
8684             }
8685 
8686             if (best == null || cur.priority > best.priority) {
8687                 if (isComponentEffectivelyEnabled(cur.getComponentInfo(), UserHandle.USER_SYSTEM)) {
8688                     best = cur;
8689                 } else {
8690                     Slog.w(TAG, "Domain verification agent found but not enabled");
8691                 }
8692             }
8693         }
8694 
8695         if (best != null) {
8696             return best.getComponentInfo().getComponentName();
8697         }
8698         Slog.w(TAG, "Domain verification agent not found");
8699         return null;
8700     }
8701 
8702     @Override
getInstantAppResolverComponent()8703     public @Nullable ComponentName getInstantAppResolverComponent() {
8704         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8705             return null;
8706         }
8707         synchronized (mLock) {
8708             final ComponentName instantAppResolver = getInstantAppResolverLPr();
8709             if (instantAppResolver == null) {
8710                 return null;
8711             }
8712             return instantAppResolver;
8713         }
8714     }
8715 
getInstantAppResolverLPr()8716     private @Nullable ComponentName getInstantAppResolverLPr() {
8717         final String[] packageArray =
8718                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
8719         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
8720             if (DEBUG_INSTANT) {
8721                 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
8722             }
8723             return null;
8724         }
8725 
8726         final int callingUid = Binder.getCallingUid();
8727         final int resolveFlags =
8728                 MATCH_DIRECT_BOOT_AWARE
8729                 | MATCH_DIRECT_BOOT_UNAWARE
8730                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
8731         final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
8732         List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
8733                 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
8734         final int N = resolvers.size();
8735         if (N == 0) {
8736             if (DEBUG_INSTANT) {
8737                 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
8738             }
8739             return null;
8740         }
8741 
8742         final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
8743         for (int i = 0; i < N; i++) {
8744             final ResolveInfo info = resolvers.get(i);
8745 
8746             if (info.serviceInfo == null) {
8747                 continue;
8748             }
8749 
8750             final String packageName = info.serviceInfo.packageName;
8751             if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
8752                 if (DEBUG_INSTANT) {
8753                     Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
8754                             + " pkg: " + packageName + ", info:" + info);
8755                 }
8756                 continue;
8757             }
8758 
8759             if (DEBUG_INSTANT) {
8760                 Slog.v(TAG, "Ephemeral resolver found;"
8761                         + " pkg: " + packageName + ", info:" + info);
8762             }
8763             return new ComponentName(packageName, info.serviceInfo.name);
8764         }
8765         if (DEBUG_INSTANT) {
8766             Slog.v(TAG, "Ephemeral resolver NOT found");
8767         }
8768         return null;
8769     }
8770 
8771     @GuardedBy("mLock")
getInstantAppInstallerLPr()8772     private @Nullable ActivityInfo getInstantAppInstallerLPr() {
8773         String[] orderedActions = mIsEngBuild
8774                 ? new String[]{
8775                         Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
8776                         Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
8777                 : new String[]{
8778                         Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
8779 
8780         final int resolveFlags =
8781                 MATCH_DIRECT_BOOT_AWARE
8782                         | MATCH_DIRECT_BOOT_UNAWARE
8783                         | Intent.FLAG_IGNORE_EPHEMERAL
8784                         | (mIsEngBuild ? 0 : MATCH_SYSTEM_ONLY);
8785         final Intent intent = new Intent();
8786         intent.addCategory(Intent.CATEGORY_DEFAULT);
8787         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
8788         List<ResolveInfo> matches = null;
8789         for (String action : orderedActions) {
8790             intent.setAction(action);
8791             matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
8792                     resolveFlags, UserHandle.USER_SYSTEM);
8793             if (matches.isEmpty()) {
8794                 if (DEBUG_INSTANT) {
8795                     Slog.d(TAG, "Instant App installer not found with " + action);
8796                 }
8797             } else {
8798                 break;
8799             }
8800         }
8801         Iterator<ResolveInfo> iter = matches.iterator();
8802         while (iter.hasNext()) {
8803             final ResolveInfo rInfo = iter.next();
8804             if (checkPermission(
8805                     Manifest.permission.INSTALL_PACKAGES,
8806                     rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || mIsEngBuild) {
8807                 continue;
8808             }
8809             iter.remove();
8810         }
8811         if (matches.size() == 0) {
8812             return null;
8813         } else if (matches.size() == 1) {
8814             return (ActivityInfo) matches.get(0).getComponentInfo();
8815         } else {
8816             throw new RuntimeException(
8817                     "There must be at most one ephemeral installer; found " + matches);
8818         }
8819     }
8820 
getInstantAppResolverSettingsLPr( @onNull ComponentName resolver)8821     private @Nullable ComponentName getInstantAppResolverSettingsLPr(
8822             @NonNull ComponentName resolver) {
8823         final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
8824                 .addCategory(Intent.CATEGORY_DEFAULT)
8825                 .setPackage(resolver.getPackageName());
8826         final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
8827         List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
8828                 UserHandle.USER_SYSTEM);
8829         if (matches.isEmpty()) {
8830             return null;
8831         }
8832         return matches.get(0).getComponentInfo().getComponentName();
8833     }
8834 
8835     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)8836     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
8837             throws RemoteException {
8838         try {
8839             return super.onTransact(code, data, reply, flags);
8840         } catch (RuntimeException e) {
8841             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
8842                 Slog.wtf(TAG, "Package Manager Crash", e);
8843             }
8844             throw e;
8845         }
8846     }
8847 
8848     /**
8849      * Returns whether or not a full application can see an instant application.
8850      * <p>
8851      * Currently, there are four cases in which this can occur:
8852      * <ol>
8853      * <li>The calling application is a "special" process. Special processes
8854      *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
8855      * <li>The calling application has the permission
8856      *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
8857      * <li>The calling application is the default launcher on the
8858      *     system partition.</li>
8859      * <li>The calling application is the default app prediction service.</li>
8860      * </ol>
8861      */
canViewInstantApps(int callingUid, int userId)8862     private boolean canViewInstantApps(int callingUid, int userId) {
8863         return mComputer.canViewInstantApps(callingUid, userId);
8864     }
8865 
generatePackageInfo(PackageSetting ps, int flags, int userId)8866     private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
8867         return mComputer.generatePackageInfo(ps, flags, userId);
8868     }
8869 
8870     @Override
checkPackageStartable(String packageName, int userId)8871     public void checkPackageStartable(String packageName, int userId) {
8872         final int callingUid = Binder.getCallingUid();
8873         if (getInstantAppPackageName(callingUid) != null) {
8874             throw new SecurityException("Instant applications don't have access to this method");
8875         }
8876         if (!mUserManager.exists(userId)) {
8877             throw new SecurityException("User doesn't exist");
8878         }
8879         enforceCrossUserPermission(callingUid, userId, false, false, "checkPackageStartable");
8880         switch (getPackageStartability(packageName, callingUid, userId)) {
8881             case PACKAGE_STARTABILITY_NOT_FOUND:
8882                 throw new SecurityException("Package " + packageName + " was not found!");
8883             case PACKAGE_STARTABILITY_NOT_SYSTEM:
8884                 throw new SecurityException("Package " + packageName + " not a system app!");
8885             case PACKAGE_STARTABILITY_FROZEN:
8886                 throw new SecurityException("Package " + packageName + " is currently frozen!");
8887             case PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED:
8888                 throw new SecurityException("Package " + packageName + " is not encryption aware!");
8889             case PACKAGE_STARTABILITY_OK:
8890             default:
8891                 return;
8892         }
8893     }
8894 
getPackageStartability(String packageName, int callingUid, int userId)8895     private @PackageStartability int getPackageStartability(String packageName,
8896             int callingUid, int userId) {
8897         final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
8898         synchronized (mLock) {
8899             final PackageSetting ps = mSettings.getPackageLPr(packageName);
8900             if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)
8901                     || !ps.getInstalled(userId)) {
8902                 return PACKAGE_STARTABILITY_NOT_FOUND;
8903             }
8904 
8905             if (mSafeMode && !ps.isSystem()) {
8906                 return PACKAGE_STARTABILITY_NOT_SYSTEM;
8907             }
8908 
8909             if (mFrozenPackages.contains(packageName)) {
8910                 return PACKAGE_STARTABILITY_FROZEN;
8911             }
8912 
8913             if (!userKeyUnlocked && !AndroidPackageUtils.isEncryptionAware(ps.pkg)) {
8914                 return PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED;
8915             }
8916         }
8917         return PACKAGE_STARTABILITY_OK;
8918     }
8919 
8920     @Override
isPackageAvailable(String packageName, int userId)8921     public boolean isPackageAvailable(String packageName, int userId) {
8922         if (!mUserManager.exists(userId)) return false;
8923         final int callingUid = Binder.getCallingUid();
8924         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
8925                 false /*checkShell*/, "is package available");
8926         synchronized (mLock) {
8927             AndroidPackage p = mPackages.get(packageName);
8928             if (p != null) {
8929                 final PackageSetting ps = getPackageSetting(p.getPackageName());
8930                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8931                     return false;
8932                 }
8933                 if (ps != null) {
8934                     final PackageUserState state = ps.readUserState(userId);
8935                     if (state != null) {
8936                         return PackageParser.isAvailable(state);
8937                     }
8938                 }
8939             }
8940         }
8941         return false;
8942     }
8943 
8944     @Override
getPackageInfo(String packageName, int flags, int userId)8945     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
8946         return mComputer.getPackageInfo(packageName, flags, userId);
8947     }
8948 
8949     @Override
getPackageInfoVersioned(VersionedPackage versionedPackage, int flags, int userId)8950     public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
8951             int flags, int userId) {
8952         return getPackageInfoInternal(versionedPackage.getPackageName(),
8953                 versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
8954     }
8955 
8956     /**
8957      * Important: The provided filterCallingUid is used exclusively to filter out packages
8958      * that can be seen based on user state. It's typically the original caller uid prior
8959      * to clearing. Because it can only be provided by trusted code, its value can be
8960      * trusted and will be used as-is; unlike userId which will be validated by this method.
8961      */
getPackageInfoInternal(String packageName, long versionCode, int flags, int filterCallingUid, int userId)8962     private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
8963             int flags, int filterCallingUid, int userId) {
8964         return mComputer.getPackageInfoInternal(packageName, versionCode,
8965                 flags, filterCallingUid, userId);
8966     }
8967 
isComponentVisibleToInstantApp(@ullable ComponentName component)8968     private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
8969         return mComputer.isComponentVisibleToInstantApp(component);
8970     }
8971 
isComponentVisibleToInstantApp( @ullable ComponentName component, @ComponentType int type)8972     private boolean isComponentVisibleToInstantApp(
8973             @Nullable ComponentName component, @ComponentType int type) {
8974         return mComputer.isComponentVisibleToInstantApp(
8975             component, type);
8976     }
8977 
8978     /**
8979      * Returns whether or not access to the application should be filtered.
8980      * <p>
8981      * Access may be limited based upon whether the calling or target applications
8982      * are instant applications.
8983      *
8984      * @see #canViewInstantApps(int, int)
8985      */
8986     @GuardedBy("mLock")
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, @Nullable ComponentName component, @ComponentType int componentType, int userId)8987     private boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
8988             @Nullable ComponentName component, @ComponentType int componentType, int userId) {
8989         return mComputer.shouldFilterApplicationLocked(ps, callingUid,
8990                 component, componentType, userId);
8991     }
8992 
8993     /**
8994      * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
8995      */
8996     @GuardedBy("mLock")
shouldFilterApplicationLocked( @ullable PackageSetting ps, int callingUid, int userId)8997     private boolean shouldFilterApplicationLocked(
8998             @Nullable PackageSetting ps, int callingUid, int userId) {
8999         return mComputer.shouldFilterApplicationLocked(
9000             ps, callingUid, userId);
9001     }
9002 
9003     /**
9004      * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
9005      */
9006     @GuardedBy("mLock")
shouldFilterApplicationLocked(@onNull SharedUserSetting sus, int callingUid, int userId)9007     private boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
9008             int userId) {
9009         return mComputer.shouldFilterApplicationLocked(sus, callingUid, userId);
9010     }
9011 
9012     @GuardedBy("mLock")
filterSharedLibPackageLPr(@ullable PackageSetting ps, int uid, int userId, int flags)9013     private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
9014             int flags) {
9015         return mComputer.filterSharedLibPackageLPr(ps, uid, userId,
9016                 flags);
9017     }
9018 
9019     @Override
currentToCanonicalPackageNames(String[] names)9020     public String[] currentToCanonicalPackageNames(String[] names) {
9021         final int callingUid = Binder.getCallingUid();
9022         if (getInstantAppPackageName(callingUid) != null) {
9023             return names;
9024         }
9025         final String[] out = new String[names.length];
9026         // reader
9027         synchronized (mLock) {
9028             final int callingUserId = UserHandle.getUserId(callingUid);
9029             final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
9030             for (int i=names.length-1; i>=0; i--) {
9031                 final PackageSetting ps = mSettings.getPackageLPr(names[i]);
9032                 boolean translateName = false;
9033                 if (ps != null && ps.realName != null) {
9034                     final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
9035                     translateName = !targetIsInstantApp
9036                             || canViewInstantApps
9037                             || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
9038                                     UserHandle.getAppId(callingUid), ps.appId);
9039                 }
9040                 out[i] = translateName ? ps.realName : names[i];
9041             }
9042         }
9043         return out;
9044     }
9045 
9046     @Override
canonicalToCurrentPackageNames(String[] names)9047     public String[] canonicalToCurrentPackageNames(String[] names) {
9048         final int callingUid = Binder.getCallingUid();
9049         if (getInstantAppPackageName(callingUid) != null) {
9050             return names;
9051         }
9052         final String[] out = new String[names.length];
9053         // reader
9054         synchronized (mLock) {
9055             final int callingUserId = UserHandle.getUserId(callingUid);
9056             final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
9057             for (int i=names.length-1; i>=0; i--) {
9058                 final String cur = mSettings.getRenamedPackageLPr(names[i]);
9059                 boolean translateName = false;
9060                 if (cur != null) {
9061                     final PackageSetting ps = mSettings.getPackageLPr(names[i]);
9062                     final boolean targetIsInstantApp =
9063                             ps != null && ps.getInstantApp(callingUserId);
9064                     translateName = !targetIsInstantApp
9065                             || canViewInstantApps
9066                             || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
9067                                     UserHandle.getAppId(callingUid), ps.appId);
9068                 }
9069                 out[i] = translateName ? cur : names[i];
9070             }
9071         }
9072         return out;
9073     }
9074 
9075     @Override
getPackageUid(String packageName, int flags, int userId)9076     public int getPackageUid(String packageName, int flags, int userId) {
9077         if (!mUserManager.exists(userId)) return -1;
9078         final int callingUid = Binder.getCallingUid();
9079         flags = updateFlagsForPackage(flags, userId);
9080         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
9081                 false /*checkShell*/, "getPackageUid");
9082         return getPackageUidInternal(packageName, flags, userId, callingUid);
9083     }
9084 
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)9085     private int getPackageUidInternal(String packageName, int flags, int userId, int callingUid) {
9086         return mComputer.getPackageUidInternal(packageName, flags, userId, callingUid);
9087     }
9088 
9089     @Override
getPackageGids(String packageName, int flags, int userId)9090     public int[] getPackageGids(String packageName, int flags, int userId) {
9091         if (!mUserManager.exists(userId)) return null;
9092         final int callingUid = Binder.getCallingUid();
9093         flags = updateFlagsForPackage(flags, userId);
9094         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
9095                 false /*checkShell*/, "getPackageGids");
9096 
9097         // reader
9098         synchronized (mLock) {
9099             final AndroidPackage p = mPackages.get(packageName);
9100             if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
9101                 PackageSetting ps = getPackageSetting(p.getPackageName());
9102                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
9103                     return null;
9104                 }
9105                 // TODO: Shouldn't this be checking for package installed state for userId and
9106                 // return null?
9107                 return mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId));
9108             }
9109             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
9110                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
9111                 if (ps != null && ps.isMatch(flags)
9112                         && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
9113                     return mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId));
9114                 }
9115             }
9116         }
9117 
9118         return null;
9119     }
9120 
9121     // NOTE: Can't remove due to unsupported app usage
9122     @Override
getPermissionGroupInfo(String groupName, int flags)9123     public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
9124         // Because this is accessed via the package manager service AIDL,
9125         // go through the permission manager service AIDL
9126         return mContext.getSystemService(PermissionManager.class)
9127                 .getPermissionGroupInfo(groupName, flags);
9128     }
9129 
9130     @GuardedBy("mLock")
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int filterCallingUid, int userId)9131     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
9132             int filterCallingUid, int userId) {
9133         return mComputer.generateApplicationInfoFromSettingsLPw(packageName, flags,
9134                 filterCallingUid, userId);
9135     }
9136 
9137     @Override
getApplicationInfo(String packageName, int flags, int userId)9138     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
9139         return mComputer.getApplicationInfo(packageName, flags, userId);
9140     }
9141 
9142     /**
9143      * Important: The provided filterCallingUid is used exclusively to filter out applications
9144      * that can be seen based on user state. It's typically the original caller uid prior
9145      * to clearing. Because it can only be provided by trusted code, its value can be
9146      * trusted and will be used as-is; unlike userId which will be validated by this method.
9147      */
getApplicationInfoInternal(String packageName, int flags, int filterCallingUid, int userId)9148     private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
9149             int filterCallingUid, int userId) {
9150         return mComputer.getApplicationInfoInternal(packageName, flags,
9151                 filterCallingUid, userId);
9152     }
9153 
9154     @GuardedBy("mLock")
normalizePackageNameLPr(String packageName)9155     private String normalizePackageNameLPr(String packageName) {
9156         String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
9157         return normalizedPackageName != null ? normalizedPackageName : packageName;
9158     }
9159 
9160     @Override
deletePreloadsFileCache()9161     public void deletePreloadsFileCache() {
9162         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
9163                 "deletePreloadsFileCache");
9164         File dir = Environment.getDataPreloadsFileCacheDirectory();
9165         Slog.i(TAG, "Deleting preloaded file cache " + dir);
9166         FileUtils.deleteContents(dir);
9167     }
9168 
9169     @Override
freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, final int storageFlags, final IPackageDataObserver observer)9170     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
9171             final int storageFlags, final IPackageDataObserver observer) {
9172         mContext.enforceCallingOrSelfPermission(
9173                 android.Manifest.permission.CLEAR_APP_CACHE, null);
9174         mHandler.post(() -> {
9175             boolean success = false;
9176             try {
9177                 freeStorage(volumeUuid, freeStorageSize, storageFlags);
9178                 success = true;
9179             } catch (IOException e) {
9180                 Slog.w(TAG, e);
9181             }
9182             if (observer != null) {
9183                 try {
9184                     observer.onRemoveCompleted(null, success);
9185                 } catch (RemoteException e) {
9186                     Slog.w(TAG, e);
9187                 }
9188             }
9189         });
9190     }
9191 
9192     @Override
freeStorage(final String volumeUuid, final long freeStorageSize, final int storageFlags, final IntentSender pi)9193     public void freeStorage(final String volumeUuid, final long freeStorageSize,
9194             final int storageFlags, final IntentSender pi) {
9195         mContext.enforceCallingOrSelfPermission(
9196                 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
9197         mHandler.post(() -> {
9198             boolean success = false;
9199             try {
9200                 freeStorage(volumeUuid, freeStorageSize, storageFlags);
9201                 success = true;
9202             } catch (IOException e) {
9203                 Slog.w(TAG, e);
9204             }
9205             if (pi != null) {
9206                 try {
9207                     pi.sendIntent(null, success ? 1 : 0, null, null, null);
9208                 } catch (SendIntentException e) {
9209                     Slog.w(TAG, e);
9210                 }
9211             }
9212         });
9213     }
9214 
9215     /**
9216      * Blocking call to clear various types of cached data across the system
9217      * until the requested bytes are available.
9218      */
freeStorage(String volumeUuid, long bytes, int storageFlags)9219     public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
9220         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
9221         final File file = storage.findPathForUuid(volumeUuid);
9222         if (file.getUsableSpace() >= bytes) return;
9223 
9224         if (mEnableFreeCacheV2) {
9225             final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
9226                     volumeUuid);
9227             final boolean aggressive = (storageFlags
9228                     & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
9229             final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
9230 
9231             // 1. Pre-flight to determine if we have any chance to succeed
9232             // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
9233             if (internalVolume && (aggressive || SystemProperties
9234                     .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
9235                 deletePreloadsFileCache();
9236                 if (file.getUsableSpace() >= bytes) return;
9237             }
9238 
9239             // 3. Consider parsed APK data (aggressive only)
9240             if (internalVolume && aggressive) {
9241                 FileUtils.deleteContents(mCacheDir);
9242                 if (file.getUsableSpace() >= bytes) return;
9243             }
9244 
9245             // 4. Consider cached app data (above quotas)
9246             try {
9247                 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
9248                         Installer.FLAG_FREE_CACHE_V2);
9249             } catch (InstallerException ignored) {
9250             }
9251             if (file.getUsableSpace() >= bytes) return;
9252 
9253             // 5. Consider shared libraries with refcount=0 and age>min cache period
9254             if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
9255                     android.provider.Settings.Global.getLong(mContext.getContentResolver(),
9256                             Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
9257                             DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
9258                 return;
9259             }
9260 
9261             // 6. Consider dexopt output (aggressive only)
9262             // TODO: Implement
9263 
9264             // 7. Consider installed instant apps unused longer than min cache period
9265             if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
9266                     android.provider.Settings.Global.getLong(mContext.getContentResolver(),
9267                             Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
9268                             InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
9269                 return;
9270             }
9271 
9272             // 8. Consider cached app data (below quotas)
9273             try {
9274                 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
9275                         Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
9276             } catch (InstallerException ignored) {
9277             }
9278             if (file.getUsableSpace() >= bytes) return;
9279 
9280             // 9. Consider DropBox entries
9281             // TODO: Implement
9282 
9283             // 10. Consider instant meta-data (uninstalled apps) older that min cache period
9284             if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
9285                     android.provider.Settings.Global.getLong(mContext.getContentResolver(),
9286                             Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
9287                             InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
9288                 return;
9289             }
9290 
9291             // 11. Free storage service cache
9292             StorageManagerInternal smInternal =
9293                     mInjector.getLocalService(StorageManagerInternal.class);
9294             long freeBytesRequired = bytes - file.getUsableSpace();
9295             if (freeBytesRequired > 0) {
9296                 smInternal.freeCache(volumeUuid, freeBytesRequired);
9297             }
9298 
9299             // 12. Clear temp install session files
9300             mInstallerService.freeStageDirs(volumeUuid);
9301 
9302             if (file.getUsableSpace() >= bytes) return;
9303         } else {
9304             try {
9305                 mInstaller.freeCache(volumeUuid, bytes, 0, 0);
9306             } catch (InstallerException ignored) {
9307             }
9308             if (file.getUsableSpace() >= bytes) return;
9309         }
9310 
9311         throw new IOException("Failed to free " + bytes + " on storage device at " + file);
9312     }
9313 
pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)9314     private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
9315             throws IOException {
9316         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
9317         final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
9318 
9319         List<VersionedPackage> packagesToDelete = null;
9320         final long now = System.currentTimeMillis();
9321 
9322         synchronized (mLock) {
9323             final int[] allUsers = mUserManager.getUserIds();
9324             final int libCount = mSharedLibraries.size();
9325             for (int i = 0; i < libCount; i++) {
9326                 final WatchedLongSparseArray<SharedLibraryInfo> versionedLib
9327                         = mSharedLibraries.valueAt(i);
9328                 if (versionedLib == null) {
9329                     continue;
9330                 }
9331                 final int versionCount = versionedLib.size();
9332                 for (int j = 0; j < versionCount; j++) {
9333                     SharedLibraryInfo libInfo = versionedLib.valueAt(j);
9334                     // Skip packages that are not static shared libs.
9335                     if (!libInfo.isStatic()) {
9336                         break;
9337                     }
9338                     // Important: We skip static shared libs used for some user since
9339                     // in such a case we need to keep the APK on the device. The check for
9340                     // a lib being used for any user is performed by the uninstall call.
9341                     final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
9342                     // Resolve the package name - we use synthetic package names internally
9343                     final String internalPackageName = resolveInternalPackageNameLPr(
9344                             declaringPackage.getPackageName(),
9345                             declaringPackage.getLongVersionCode());
9346                     final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
9347                     // Skip unused static shared libs cached less than the min period
9348                     // to prevent pruning a lib needed by a subsequently installed package.
9349                     if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
9350                         continue;
9351                     }
9352 
9353                     if (ps.pkg.isSystem()) {
9354                         continue;
9355                     }
9356 
9357                     if (packagesToDelete == null) {
9358                         packagesToDelete = new ArrayList<>();
9359                     }
9360                     packagesToDelete.add(new VersionedPackage(internalPackageName,
9361                             declaringPackage.getLongVersionCode()));
9362                 }
9363             }
9364         }
9365 
9366         if (packagesToDelete != null) {
9367             final int packageCount = packagesToDelete.size();
9368             for (int i = 0; i < packageCount; i++) {
9369                 final VersionedPackage pkgToDelete = packagesToDelete.get(i);
9370                 // Delete the package synchronously (will fail of the lib used for any user).
9371                 if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
9372                         UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS,
9373                         true /*removedBySystem*/) == PackageManager.DELETE_SUCCEEDED) {
9374                     if (volume.getUsableSpace() >= neededSpace) {
9375                         return true;
9376                     }
9377                 }
9378             }
9379         }
9380 
9381         return false;
9382     }
9383 
9384     /**
9385      * Update given flags when being used to request {@link PackageInfo}.
9386      */
updateFlagsForPackage(int flags, int userId)9387     private int updateFlagsForPackage(int flags, int userId) {
9388         return mComputer.updateFlagsForPackage(flags, userId);
9389     }
9390 
9391     /**
9392      * Update given flags when being used to request {@link ApplicationInfo}.
9393      */
updateFlagsForApplication(int flags, int userId)9394     private int updateFlagsForApplication(int flags, int userId) {
9395         return mComputer.updateFlagsForApplication(flags, userId);
9396     }
9397 
9398     /**
9399      * Update given flags when being used to request {@link ComponentInfo}.
9400      */
updateFlagsForComponent(int flags, int userId)9401     private int updateFlagsForComponent(int flags, int userId) {
9402         return mComputer.updateFlagsForComponent(flags, userId);
9403     }
9404 
9405     /**
9406      * Update given intent when being used to request {@link ResolveInfo}.
9407      */
updateIntentForResolve(Intent intent)9408     private static Intent updateIntentForResolve(Intent intent) {
9409         if (intent.getSelector() != null) {
9410             intent = intent.getSelector();
9411         }
9412         if (DEBUG_PREFERRED) {
9413             intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
9414         }
9415         return intent;
9416     }
9417 
9418     /**
9419      * Update given flags when being used to request {@link ResolveInfo}.
9420      * <p>Instant apps are resolved specially, depending upon context. Minimally,
9421      * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
9422      * flag set. However, this flag is only honoured in three circumstances:
9423      * <ul>
9424      * <li>when called from a system process</li>
9425      * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
9426      * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
9427      * action and a {@code android.intent.category.BROWSABLE} category</li>
9428      * </ul>
9429      */
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc)9430     private int updateFlagsForResolve(int flags, int userId, int callingUid,
9431             boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
9432         return mComputer.updateFlagsForResolve(flags, userId, callingUid,
9433                 wantInstantApps, isImplicitImageCaptureIntentAndNotSetByDpc);
9434     }
9435 
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc)9436     private int updateFlagsForResolve(int flags, int userId, int callingUid,
9437             boolean wantInstantApps, boolean onlyExposedExplicitly,
9438             boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
9439         return mComputer.updateFlagsForResolve(flags, userId, callingUid,
9440                 wantInstantApps, onlyExposedExplicitly,
9441                 isImplicitImageCaptureIntentAndNotSetByDpc);
9442     }
9443 
9444     @Override
getTargetSdkVersion(String packageName)9445     public int getTargetSdkVersion(String packageName)  {
9446         synchronized (mLock) {
9447             final AndroidPackage pkg = mPackages.get(packageName);
9448             if (pkg == null) {
9449                 return -1;
9450             }
9451 
9452             final PackageSetting ps = getPackageSetting(pkg.getPackageName());
9453             if (shouldFilterApplicationLocked(ps, Binder.getCallingUid(),
9454                     UserHandle.getCallingUserId())) {
9455                 return -1;
9456             }
9457             return pkg.getTargetSdkVersion();
9458         }
9459     }
9460 
9461     @Override
getActivityInfo(ComponentName component, int flags, int userId)9462     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
9463         return mComputer.getActivityInfo(component, flags, userId);
9464     }
9465 
9466     /**
9467      * Important: The provided filterCallingUid is used exclusively to filter out activities
9468      * that can be seen based on user state. It's typically the original caller uid prior
9469      * to clearing. Because it can only be provided by trusted code, its value can be
9470      * trusted and will be used as-is; unlike userId which will be validated by this method.
9471      */
getActivityInfoInternal(ComponentName component, int flags, int filterCallingUid, int userId)9472     private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
9473             int filterCallingUid, int userId) {
9474         return mComputer.getActivityInfoInternal(component, flags,
9475                 filterCallingUid, userId);
9476     }
9477 
9478     @Override
activitySupportsIntent(ComponentName component, Intent intent, String resolvedType)9479     public boolean activitySupportsIntent(ComponentName component, Intent intent,
9480             String resolvedType) {
9481         synchronized (mLock) {
9482             if (component.equals(mResolveComponentName)) {
9483                 // The resolver supports EVERYTHING!
9484                 return true;
9485             }
9486             final int callingUid = Binder.getCallingUid();
9487             final int callingUserId = UserHandle.getUserId(callingUid);
9488             ParsedActivity a = mComponentResolver.getActivity(component);
9489             if (a == null) {
9490                 return false;
9491             }
9492             PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
9493             if (ps == null) {
9494                 return false;
9495             }
9496             if (shouldFilterApplicationLocked(
9497                     ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
9498                 return false;
9499             }
9500             for (int i=0; i< a.getIntents().size(); i++) {
9501                 if (a.getIntents().get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
9502                         intent.getData(), intent.getCategories(), TAG) >= 0) {
9503                     return true;
9504                 }
9505             }
9506             return false;
9507         }
9508     }
9509 
9510     @Override
getReceiverInfo(ComponentName component, int flags, int userId)9511     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
9512         if (!mUserManager.exists(userId)) return null;
9513         final int callingUid = Binder.getCallingUid();
9514         flags = updateFlagsForComponent(flags, userId);
9515         enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
9516                 false /* checkShell */, "get receiver info");
9517         synchronized (mLock) {
9518             ParsedActivity a = mComponentResolver.getReceiver(component);
9519             if (DEBUG_PACKAGE_INFO) Log.v(
9520                 TAG, "getReceiverInfo " + component + ": " + a);
9521 
9522             if (a == null) {
9523                 return null;
9524             }
9525 
9526             AndroidPackage pkg = mPackages.get(a.getPackageName());
9527             if (pkg == null) {
9528                 return null;
9529             }
9530 
9531             if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
9532                 PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
9533                 if (ps == null) return null;
9534                 if (shouldFilterApplicationLocked(
9535                         ps, callingUid, component, TYPE_RECEIVER, userId)) {
9536                     return null;
9537                 }
9538                 return PackageInfoUtils.generateActivityInfo(pkg,
9539                         a, flags, ps.readUserState(userId), userId, ps);
9540             }
9541         }
9542         return null;
9543     }
9544 
9545     @Override
getSharedLibraries(String packageName, int flags, int userId)9546     public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
9547             int flags, int userId) {
9548         if (!mUserManager.exists(userId)) return null;
9549         Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
9550         final int callingUid = Binder.getCallingUid();
9551         if (getInstantAppPackageName(callingUid) != null) {
9552             return null;
9553         }
9554 
9555         flags = updateFlagsForPackage(flags, userId);
9556 
9557         final boolean canSeeStaticLibraries =
9558                 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
9559                         == PERMISSION_GRANTED
9560                 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
9561                         == PERMISSION_GRANTED
9562                 || canRequestPackageInstallsInternal(packageName, callingUid, userId,
9563                         false  /* throwIfPermNotDeclared*/)
9564                 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
9565                         == PERMISSION_GRANTED
9566                 || mContext.checkCallingOrSelfPermission(
9567                         Manifest.permission.ACCESS_SHARED_LIBRARIES) == PERMISSION_GRANTED;
9568 
9569         synchronized (mLock) {
9570             List<SharedLibraryInfo> result = null;
9571 
9572             final int libCount = mSharedLibraries.size();
9573             for (int i = 0; i < libCount; i++) {
9574                 WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
9575                         mSharedLibraries.valueAt(i);
9576                 if (versionedLib == null) {
9577                     continue;
9578                 }
9579 
9580                 final int versionCount = versionedLib.size();
9581                 for (int j = 0; j < versionCount; j++) {
9582                     SharedLibraryInfo libInfo = versionedLib.valueAt(j);
9583                     if (!canSeeStaticLibraries && libInfo.isStatic()) {
9584                         break;
9585                     }
9586                     final long identity = Binder.clearCallingIdentity();
9587                     try {
9588                         PackageInfo packageInfo = getPackageInfoVersioned(
9589                                 libInfo.getDeclaringPackage(), flags
9590                                         | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
9591                         if (packageInfo == null) {
9592                             continue;
9593                         }
9594                     } finally {
9595                         Binder.restoreCallingIdentity(identity);
9596                     }
9597 
9598                     SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
9599                             libInfo.getPackageName(), libInfo.getAllCodePaths(),
9600                             libInfo.getName(), libInfo.getLongVersion(),
9601                             libInfo.getType(), libInfo.getDeclaringPackage(),
9602                             getPackagesUsingSharedLibraryLPr(libInfo, flags, callingUid, userId),
9603                             (libInfo.getDependencies() == null
9604                                     ? null
9605                                     : new ArrayList<>(libInfo.getDependencies())),
9606                             libInfo.isNative());
9607 
9608                     if (result == null) {
9609                         result = new ArrayList<>();
9610                     }
9611                     result.add(resLibInfo);
9612                 }
9613             }
9614 
9615             return result != null ? new ParceledListSlice<>(result) : null;
9616         }
9617     }
9618 
9619     @Nullable
9620     @Override
getDeclaredSharedLibraries( @onNull String packageName, int flags, @NonNull int userId)9621     public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
9622             @NonNull String packageName, int flags, @NonNull int userId) {
9623         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES,
9624                 "getDeclaredSharedLibraries");
9625         int callingUid = Binder.getCallingUid();
9626         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
9627                 false /* checkShell */, "getDeclaredSharedLibraries");
9628 
9629         Preconditions.checkNotNull(packageName, "packageName cannot be null");
9630         Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
9631         if (!mUserManager.exists(userId)) {
9632             return null;
9633         }
9634 
9635         if (getInstantAppPackageName(callingUid) != null) {
9636             return null;
9637         }
9638 
9639         synchronized (mLock) {
9640             List<SharedLibraryInfo> result = null;
9641 
9642             int libraryCount = mSharedLibraries.size();
9643             for (int i = 0; i < libraryCount; i++) {
9644                 WatchedLongSparseArray<SharedLibraryInfo> versionedLibrary =
9645                         mSharedLibraries.valueAt(i);
9646                 if (versionedLibrary == null) {
9647                     continue;
9648                 }
9649 
9650                 int versionCount = versionedLibrary.size();
9651                 for (int j = 0; j < versionCount; j++) {
9652                     SharedLibraryInfo libraryInfo = versionedLibrary.valueAt(j);
9653 
9654                     VersionedPackage declaringPackage = libraryInfo.getDeclaringPackage();
9655                     if (!Objects.equals(declaringPackage.getPackageName(), packageName)) {
9656                         continue;
9657                     }
9658 
9659                     final long identity = Binder.clearCallingIdentity();
9660                     try {
9661                         PackageInfo packageInfo = getPackageInfoVersioned(declaringPackage, flags
9662                                 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
9663                         if (packageInfo == null) {
9664                             continue;
9665                         }
9666                     } finally {
9667                         Binder.restoreCallingIdentity(identity);
9668                     }
9669 
9670                     SharedLibraryInfo resultLibraryInfo = new SharedLibraryInfo(
9671                             libraryInfo.getPath(), libraryInfo.getPackageName(),
9672                             libraryInfo.getAllCodePaths(), libraryInfo.getName(),
9673                             libraryInfo.getLongVersion(), libraryInfo.getType(),
9674                             libraryInfo.getDeclaringPackage(),
9675                             getPackagesUsingSharedLibraryLPr(
9676                                     libraryInfo, flags, callingUid, userId),
9677                             libraryInfo.getDependencies() == null
9678                                     ? null : new ArrayList<>(libraryInfo.getDependencies()),
9679                             libraryInfo.isNative());
9680 
9681                     if (result == null) {
9682                         result = new ArrayList<>();
9683                     }
9684                     result.add(resultLibraryInfo);
9685                 }
9686             }
9687 
9688             return result != null ? new ParceledListSlice<>(result) : null;
9689         }
9690     }
9691 
9692     @GuardedBy("mLock")
getPackagesUsingSharedLibraryLPr( SharedLibraryInfo libInfo, int flags, int callingUid, int userId)9693     private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
9694             SharedLibraryInfo libInfo, int flags, int callingUid, int userId) {
9695         List<VersionedPackage> versionedPackages = null;
9696         final int packageCount = mSettings.getPackagesLocked().size();
9697         for (int i = 0; i < packageCount; i++) {
9698             PackageSetting ps = mSettings.getPackagesLocked().valueAt(i);
9699 
9700             if (ps == null) {
9701                 continue;
9702             }
9703 
9704             if (!ps.readUserState(userId).isAvailable(flags)) {
9705                 continue;
9706             }
9707 
9708             final String libName = libInfo.getName();
9709             if (libInfo.isStatic()) {
9710                 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
9711                 if (libIdx < 0) {
9712                     continue;
9713                 }
9714                 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
9715                     continue;
9716                 }
9717                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
9718                     continue;
9719                 }
9720                 if (versionedPackages == null) {
9721                     versionedPackages = new ArrayList<>();
9722                 }
9723                 // If the dependent is a static shared lib, use the public package name
9724                 String dependentPackageName = ps.name;
9725                 if (ps.pkg != null && ps.pkg.isStaticSharedLibrary()) {
9726                     dependentPackageName = ps.pkg.getManifestPackageName();
9727                 }
9728                 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
9729             } else if (ps.pkg != null) {
9730                 if (ArrayUtils.contains(ps.pkg.getUsesLibraries(), libName)
9731                         || ArrayUtils.contains(ps.pkg.getUsesOptionalLibraries(), libName)) {
9732                     if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
9733                         continue;
9734                     }
9735                     if (versionedPackages == null) {
9736                         versionedPackages = new ArrayList<>();
9737                     }
9738                     versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
9739                 }
9740             }
9741         }
9742 
9743         return versionedPackages;
9744     }
9745 
9746     @Override
getServiceInfo(ComponentName component, int flags, int userId)9747     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
9748         return mComputer.getServiceInfo(component, flags, userId);
9749     }
9750 
9751     @Override
getProviderInfo(ComponentName component, int flags, int userId)9752     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
9753         if (!mUserManager.exists(userId)) return null;
9754         final int callingUid = Binder.getCallingUid();
9755         flags = updateFlagsForComponent(flags, userId);
9756         enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
9757                 false /* checkShell */, "get provider info");
9758         synchronized (mLock) {
9759             ParsedProvider p = mComponentResolver.getProvider(component);
9760             if (DEBUG_PACKAGE_INFO) Log.v(
9761                     TAG, "getProviderInfo " + component + ": " + p);
9762             if (p == null) {
9763                 return null;
9764             }
9765 
9766             AndroidPackage pkg = mPackages.get(p.getPackageName());
9767             if (pkg == null) {
9768                 return null;
9769             }
9770 
9771             if (mSettings.isEnabledAndMatchLPr(pkg, p, flags, userId)) {
9772                 PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
9773                 if (ps == null) return null;
9774                 if (shouldFilterApplicationLocked(
9775                         ps, callingUid, component, TYPE_PROVIDER, userId)) {
9776                     return null;
9777                 }
9778                 PackageUserState state = ps.readUserState(userId);
9779                 final ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
9780                         pkg, flags, state, userId, ps);
9781                 if (appInfo == null) {
9782                     return null;
9783                 }
9784                 return PackageInfoUtils.generateProviderInfo(
9785                         pkg, p, flags, state, appInfo, userId, ps);
9786             }
9787         }
9788         return null;
9789     }
9790 
9791     @Override
getModuleInfo(String packageName, @ModuleInfoFlags int flags)9792     public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) {
9793         return mModuleInfoProvider.getModuleInfo(packageName, flags);
9794     }
9795 
9796     @Override
getInstalledModules(int flags)9797     public List<ModuleInfo> getInstalledModules(int flags) {
9798         return mModuleInfoProvider.getInstalledModules(flags);
9799     }
9800 
9801     @Override
getSystemSharedLibraryNames()9802     public String[] getSystemSharedLibraryNames() {
9803         // allow instant applications
9804         synchronized (mLock) {
9805             Set<String> libs = null;
9806             final int libCount = mSharedLibraries.size();
9807             for (int i = 0; i < libCount; i++) {
9808                 WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
9809                         mSharedLibraries.valueAt(i);
9810                 if (versionedLib == null) {
9811                     continue;
9812                 }
9813                 final int versionCount = versionedLib.size();
9814                 for (int j = 0; j < versionCount; j++) {
9815                     SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
9816                     if (!libraryInfo.isStatic()) {
9817                         if (libs == null) {
9818                             libs = new ArraySet<>();
9819                         }
9820                         libs.add(libraryInfo.getName());
9821                         break;
9822                     }
9823                     PackageSetting ps = mSettings.getPackageLPr(libraryInfo.getPackageName());
9824                     if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
9825                             UserHandle.getUserId(Binder.getCallingUid()),
9826                             PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
9827                         if (libs == null) {
9828                             libs = new ArraySet<>();
9829                         }
9830                         libs.add(libraryInfo.getName());
9831                         break;
9832                     }
9833                 }
9834             }
9835 
9836             if (libs != null) {
9837                 String[] libsArray = new String[libs.size()];
9838                 libs.toArray(libsArray);
9839                 return libsArray;
9840             }
9841 
9842             return null;
9843         }
9844     }
9845 
9846     @Override
getServicesSystemSharedLibraryPackageName()9847     public @NonNull String getServicesSystemSharedLibraryPackageName() {
9848         // allow instant applications
9849         synchronized (mLock) {
9850             return mServicesExtensionPackageName;
9851         }
9852     }
9853 
9854     @Override
getSharedSystemSharedLibraryPackageName()9855     public @NonNull String getSharedSystemSharedLibraryPackageName() {
9856         // allow instant applications
9857         synchronized (mLock) {
9858             return mSharedSystemSharedLibraryPackageName;
9859         }
9860     }
9861 
9862     @GuardedBy("mLock")
updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList)9863     private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
9864         for (int i = userList.length - 1; i >= 0; --i) {
9865             final int userId = userList[i];
9866             SparseArray<String> changedPackages = mChangedPackages.get(userId);
9867             if (changedPackages == null) {
9868                 changedPackages = new SparseArray<>();
9869                 mChangedPackages.put(userId, changedPackages);
9870             }
9871             Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
9872             if (sequenceNumbers == null) {
9873                 sequenceNumbers = new HashMap<>();
9874                 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
9875             }
9876             final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
9877             if (sequenceNumber != null) {
9878                 changedPackages.remove(sequenceNumber);
9879             }
9880             changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
9881             sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
9882         }
9883         mChangedPackagesSequenceNumber++;
9884     }
9885 
9886     @Override
getChangedPackages(int sequenceNumber, int userId)9887     public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
9888         final int callingUid = Binder.getCallingUid();
9889         if (getInstantAppPackageName(callingUid) != null) {
9890             return null;
9891         }
9892         if (!mUserManager.exists(userId)) {
9893             return null;
9894         }
9895         enforceCrossUserPermission(callingUid, userId, false, false, "getChangedPackages");
9896         synchronized (mLock) {
9897             if (sequenceNumber >= mChangedPackagesSequenceNumber) {
9898                 return null;
9899             }
9900             final SparseArray<String> changedPackages = mChangedPackages.get(userId);
9901             if (changedPackages == null) {
9902                 return null;
9903             }
9904             final List<String> packageNames =
9905                     new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
9906             for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
9907                 final String packageName = changedPackages.get(i);
9908                 if (packageName != null) {
9909                     // Filter out the changes if the calling package should not be able to see it.
9910                     final PackageSetting ps = mSettings.getPackageLPr(packageName);
9911                     if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
9912                         continue;
9913                     }
9914                     packageNames.add(packageName);
9915                 }
9916             }
9917             return packageNames.isEmpty()
9918                     ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
9919         }
9920     }
9921 
9922     @Override
getSystemAvailableFeatures()9923     public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
9924         // allow instant applications
9925         ArrayList<FeatureInfo> res;
9926         synchronized (mAvailableFeatures) {
9927             res = new ArrayList<>(mAvailableFeatures.size() + 1);
9928             res.addAll(mAvailableFeatures.values());
9929         }
9930         final FeatureInfo fi = new FeatureInfo();
9931         fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
9932                 FeatureInfo.GL_ES_VERSION_UNDEFINED);
9933         res.add(fi);
9934 
9935         return new ParceledListSlice<>(res);
9936     }
9937 
9938     @Override
hasSystemFeature(String name, int version)9939     public boolean hasSystemFeature(String name, int version) {
9940         // allow instant applications
9941         synchronized (mAvailableFeatures) {
9942             final FeatureInfo feat = mAvailableFeatures.get(name);
9943             if (feat == null) {
9944                 return false;
9945             } else {
9946                 return feat.version >= version;
9947             }
9948         }
9949     }
9950 
9951     // NOTE: Can't remove due to unsupported app usage
9952     @Override
checkPermission(String permName, String pkgName, int userId)9953     public int checkPermission(String permName, String pkgName, int userId) {
9954         return mPermissionManager.checkPermission(pkgName, permName, userId);
9955     }
9956 
9957     // NOTE: Can't remove without a major refactor. Keep around for now.
9958     @Override
checkUidPermission(String permName, int uid)9959     public int checkUidPermission(String permName, int uid) {
9960         return mComputer.checkUidPermission(permName, uid);
9961     }
9962 
9963     @Override
getPermissionControllerPackageName()9964     public String getPermissionControllerPackageName() {
9965         synchronized (mLock) {
9966             if (mRequiredPermissionControllerPackage != null) {
9967                 final PackageSetting ps = getPackageSetting(mRequiredPermissionControllerPackage);
9968                 if (ps != null) {
9969                     final int callingUid = Binder.getCallingUid();
9970                     final int callingUserId = UserHandle.getUserId(callingUid);
9971                     if (!shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
9972                         return mRequiredPermissionControllerPackage;
9973                     }
9974                 }
9975             }
9976             throw new IllegalStateException("PermissionController is not found");
9977         }
9978     }
9979 
getPackageInstallerPackageName()9980     String getPackageInstallerPackageName() {
9981         synchronized (mLock) {
9982             return mRequiredInstallerPackage;
9983         }
9984     }
9985 
9986     // NOTE: Can't remove due to unsupported app usage
9987     @Override
addPermission(PermissionInfo info)9988     public boolean addPermission(PermissionInfo info) {
9989         // Because this is accessed via the package manager service AIDL,
9990         // go through the permission manager service AIDL
9991         return mContext.getSystemService(PermissionManager.class).addPermission(info, false);
9992     }
9993 
9994     // NOTE: Can't remove due to unsupported app usage
9995     @Override
addPermissionAsync(PermissionInfo info)9996     public boolean addPermissionAsync(PermissionInfo info) {
9997         // Because this is accessed via the package manager service AIDL,
9998         // go through the permission manager service AIDL
9999         return mContext.getSystemService(PermissionManager.class).addPermission(info, true);
10000     }
10001 
10002     // NOTE: Can't remove due to unsupported app usage
10003     @Override
removePermission(String permName)10004     public void removePermission(String permName) {
10005         // Because this is accessed via the package manager service AIDL,
10006         // go through the permission manager service AIDL
10007         mContext.getSystemService(PermissionManager.class).removePermission(permName);
10008     }
10009 
10010     // NOTE: Can't remove due to unsupported app usage
10011     @Override
grantRuntimePermission(String packageName, String permName, final int userId)10012     public void grantRuntimePermission(String packageName, String permName, final int userId) {
10013         // Because this is accessed via the package manager service AIDL,
10014         // go through the permission manager service AIDL
10015         mContext.getSystemService(PermissionManager.class)
10016                 .grantRuntimePermission(packageName, permName, UserHandle.of(userId));
10017     }
10018 
10019     @Override
isProtectedBroadcast(String actionName)10020     public boolean isProtectedBroadcast(String actionName) {
10021         if (actionName != null) {
10022             // TODO: remove these terrible hacks
10023             if (actionName.startsWith("android.net.netmon.lingerExpired")
10024                     || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
10025                     || actionName.startsWith("com.android.internal.telephony.data-reconnect")
10026                     || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
10027                 return true;
10028             }
10029         }
10030          // allow instant applications
10031         synchronized (mProtectedBroadcasts) {
10032             return mProtectedBroadcasts.contains(actionName);
10033         }
10034     }
10035 
10036     @Override
checkSignatures(String pkg1, String pkg2)10037     public int checkSignatures(String pkg1, String pkg2) {
10038         synchronized (mLock) {
10039             final AndroidPackage p1 = mPackages.get(pkg1);
10040             final AndroidPackage p2 = mPackages.get(pkg2);
10041             final PackageSetting ps1 = p1 == null ? null : getPackageSetting(p1.getPackageName());
10042             final PackageSetting ps2 = p2 == null ? null : getPackageSetting(p2.getPackageName());
10043             if (p1 == null || ps1 == null || p2 == null || ps2 == null) {
10044                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10045             }
10046             final int callingUid = Binder.getCallingUid();
10047             final int callingUserId = UserHandle.getUserId(callingUid);
10048             if (shouldFilterApplicationLocked(ps1, callingUid, callingUserId)
10049                     || shouldFilterApplicationLocked(ps2, callingUid, callingUserId)) {
10050                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10051             }
10052             return checkSignaturesInternal(p1.getSigningDetails(), p2.getSigningDetails());
10053         }
10054     }
10055 
10056     @Override
checkUidSignatures(int uid1, int uid2)10057     public int checkUidSignatures(int uid1, int uid2) {
10058         final int callingUid = Binder.getCallingUid();
10059         final int callingUserId = UserHandle.getUserId(callingUid);
10060         // Map to base uids.
10061         final int appId1 = UserHandle.getAppId(uid1);
10062         final int appId2 = UserHandle.getAppId(uid2);
10063         // reader
10064         synchronized (mLock) {
10065             SigningDetails p1SigningDetails;
10066             SigningDetails p2SigningDetails;
10067             Object obj = mSettings.getSettingLPr(appId1);
10068             if (obj != null) {
10069                 if (obj instanceof SharedUserSetting) {
10070                     final SharedUserSetting sus = (SharedUserSetting) obj;
10071                     if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10072                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10073                     }
10074                     p1SigningDetails = sus.signatures.mSigningDetails;
10075                 } else if (obj instanceof PackageSetting) {
10076                     final PackageSetting ps = (PackageSetting) obj;
10077                     if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10078                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10079                     }
10080                     p1SigningDetails = ps.signatures.mSigningDetails;
10081                 } else {
10082                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10083                 }
10084             } else {
10085                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10086             }
10087             obj = mSettings.getSettingLPr(appId2);
10088             if (obj != null) {
10089                 if (obj instanceof SharedUserSetting) {
10090                     final SharedUserSetting sus = (SharedUserSetting) obj;
10091                     if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10092                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10093                     }
10094                     p2SigningDetails = sus.signatures.mSigningDetails;
10095                 } else if (obj instanceof PackageSetting) {
10096                     final PackageSetting ps = (PackageSetting) obj;
10097                     if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10098                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10099                     }
10100                     p2SigningDetails = ps.signatures.mSigningDetails;
10101                 } else {
10102                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10103                 }
10104             } else {
10105                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
10106             }
10107             return checkSignaturesInternal(p1SigningDetails, p2SigningDetails);
10108         }
10109     }
10110 
checkSignaturesInternal(SigningDetails p1SigningDetails, SigningDetails p2SigningDetails)10111     private int checkSignaturesInternal(SigningDetails p1SigningDetails,
10112             SigningDetails p2SigningDetails) {
10113         if (p1SigningDetails == null) {
10114             return p2SigningDetails == null
10115                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
10116                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
10117         }
10118         if (p2SigningDetails == null) {
10119             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
10120         }
10121         int result = compareSignatures(p1SigningDetails.signatures, p2SigningDetails.signatures);
10122         if (result == PackageManager.SIGNATURE_MATCH) {
10123             return result;
10124         }
10125         // To support backwards compatibility with clients of this API expecting pre-key
10126         // rotation results if either of the packages has a signing lineage the oldest signer
10127         // in the lineage is used for signature verification.
10128         if (p1SigningDetails.hasPastSigningCertificates()
10129                 || p2SigningDetails.hasPastSigningCertificates()) {
10130             Signature[] p1Signatures = p1SigningDetails.hasPastSigningCertificates()
10131                     ? new Signature[]{p1SigningDetails.pastSigningCertificates[0]}
10132                     : p1SigningDetails.signatures;
10133             Signature[] p2Signatures = p2SigningDetails.hasPastSigningCertificates()
10134                     ? new Signature[]{p2SigningDetails.pastSigningCertificates[0]}
10135                     : p2SigningDetails.signatures;
10136             result = compareSignatures(p1Signatures, p2Signatures);
10137         }
10138         return result;
10139     }
10140 
10141     @Override
hasSigningCertificate( String packageName, byte[] certificate, @PackageManager.CertificateInputType int type)10142     public boolean hasSigningCertificate(
10143             String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
10144 
10145         synchronized (mLock) {
10146             final AndroidPackage p = mPackages.get(packageName);
10147             if (p == null) {
10148                 return false;
10149             }
10150             final PackageSetting ps = getPackageSetting(p.getPackageName());
10151             if (ps == null) {
10152                 return false;
10153             }
10154             final int callingUid = Binder.getCallingUid();
10155             final int callingUserId = UserHandle.getUserId(callingUid);
10156             if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10157                 return false;
10158             }
10159             switch (type) {
10160                 case CERT_INPUT_RAW_X509:
10161                     return p.getSigningDetails().hasCertificate(certificate);
10162                 case CERT_INPUT_SHA256:
10163                     return p.getSigningDetails().hasSha256Certificate(certificate);
10164                 default:
10165                     return false;
10166             }
10167         }
10168     }
10169 
10170     @Override
hasUidSigningCertificate( int uid, byte[] certificate, @PackageManager.CertificateInputType int type)10171     public boolean hasUidSigningCertificate(
10172             int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
10173         final int callingUid = Binder.getCallingUid();
10174         final int callingUserId = UserHandle.getUserId(callingUid);
10175         // Map to base uids.
10176         final int appId = UserHandle.getAppId(uid);
10177         // reader
10178         synchronized (mLock) {
10179             final PackageParser.SigningDetails signingDetails;
10180             final Object obj = mSettings.getSettingLPr(appId);
10181             if (obj != null) {
10182                 if (obj instanceof SharedUserSetting) {
10183                     final SharedUserSetting sus = (SharedUserSetting) obj;
10184                     if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10185                         return false;
10186                     }
10187                     signingDetails = sus.signatures.mSigningDetails;
10188                 } else if (obj instanceof PackageSetting) {
10189                     final PackageSetting ps = (PackageSetting) obj;
10190                     if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10191                         return false;
10192                     }
10193                     signingDetails = ps.signatures.mSigningDetails;
10194                 } else {
10195                     return false;
10196                 }
10197             } else {
10198                 return false;
10199             }
10200             switch (type) {
10201                 case CERT_INPUT_RAW_X509:
10202                     return signingDetails.hasCertificate(certificate);
10203                 case CERT_INPUT_SHA256:
10204                     return signingDetails.hasSha256Certificate(certificate);
10205                 default:
10206                     return false;
10207             }
10208         }
10209     }
10210 
10211     /**
10212      * If the database version for this type of package (internal storage or
10213      * external storage) is less than the version where package signatures
10214      * were updated, return true.
10215      */
isCompatSignatureUpdateNeeded(AndroidPackage pkg)10216     private boolean isCompatSignatureUpdateNeeded(AndroidPackage pkg) {
10217         return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
10218     }
10219 
isCompatSignatureUpdateNeeded(VersionInfo ver)10220     private static boolean isCompatSignatureUpdateNeeded(VersionInfo ver) {
10221         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
10222     }
10223 
isRecoverSignatureUpdateNeeded(AndroidPackage pkg)10224     private boolean isRecoverSignatureUpdateNeeded(AndroidPackage pkg) {
10225         return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
10226     }
10227 
isRecoverSignatureUpdateNeeded(VersionInfo ver)10228     private static boolean isRecoverSignatureUpdateNeeded(VersionInfo ver) {
10229         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
10230     }
10231 
10232     @Override
getAllPackages()10233     public List<String> getAllPackages() {
10234         // Allow iorapd to call this method.
10235         if (Binder.getCallingUid() != Process.IORAPD_UID) {
10236             enforceSystemOrRootOrShell("getAllPackages is limited to privileged callers");
10237         }
10238         final int callingUid = Binder.getCallingUid();
10239         final int callingUserId = UserHandle.getUserId(callingUid);
10240         synchronized (mLock) {
10241             if (canViewInstantApps(callingUid, callingUserId)) {
10242                 return new ArrayList<>(mPackages.keySet());
10243             }
10244             final String instantAppPkgName = getInstantAppPackageName(callingUid);
10245             final List<String> result = new ArrayList<>();
10246             if (instantAppPkgName != null) {
10247                 // caller is an instant application; filter unexposed applications
10248                 for (AndroidPackage pkg : mPackages.values()) {
10249                     if (!pkg.isVisibleToInstantApps()) {
10250                         continue;
10251                     }
10252                     result.add(pkg.getPackageName());
10253                 }
10254             } else {
10255                 // caller is a normal application; filter instant applications
10256                 for (AndroidPackage pkg : mPackages.values()) {
10257                     final PackageSetting ps = getPackageSetting(pkg.getPackageName());
10258                     if (ps != null
10259                             && ps.getInstantApp(callingUserId)
10260                             && !mInstantAppRegistry.isInstantAccessGranted(
10261                                     callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
10262                         continue;
10263                     }
10264                     result.add(pkg.getPackageName());
10265                 }
10266             }
10267             return result;
10268         }
10269     }
10270 
10271     /**
10272      * <em>IMPORTANT:</em> Not all packages returned by this method may be known
10273      * to the system. There are two conditions in which this may occur:
10274      * <ol>
10275      *   <li>The package is on adoptable storage and the device has been removed</li>
10276      *   <li>The package is being removed and the internal structures are partially updated</li>
10277      * </ol>
10278      * The second is an artifact of the current data structures and should be fixed. See
10279      * b/111075456 for one such instance.
10280      * This binder API is cached.  If the algorithm in this method changes,
10281      * or if the underlying objecs (as returned by getSettingLPr()) change
10282      * then the logic that invalidates the cache must be revisited.  See
10283      * calls to invalidateGetPackagesForUidCache() to locate the points at
10284      * which the cache is invalidated.
10285      */
10286     @Override
getPackagesForUid(int uid)10287     public String[] getPackagesForUid(int uid) {
10288         final int callingUid = Binder.getCallingUid();
10289         final int userId = UserHandle.getUserId(uid);
10290         enforceCrossUserOrProfilePermission(callingUid, userId,
10291                 /* requireFullPermission */ false,
10292                 /* checkShell */ false, "getPackagesForUid");
10293         return mComputer.getPackagesForUid(uid);
10294     }
10295 
10296     @Override
getNameForUid(int uid)10297     public String getNameForUid(int uid) {
10298         final int callingUid = Binder.getCallingUid();
10299         if (getInstantAppPackageName(callingUid) != null) {
10300             return null;
10301         }
10302         final int callingUserId = UserHandle.getUserId(callingUid);
10303         final int appId = UserHandle.getAppId(uid);
10304         synchronized (mLock) {
10305             final Object obj = mSettings.getSettingLPr(appId);
10306             if (obj instanceof SharedUserSetting) {
10307                 final SharedUserSetting sus = (SharedUserSetting) obj;
10308                 if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10309                     return null;
10310                 }
10311                 return sus.name + ":" + sus.userId;
10312             } else if (obj instanceof PackageSetting) {
10313                 final PackageSetting ps = (PackageSetting) obj;
10314                 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10315                     return null;
10316                 }
10317                 return ps.name;
10318             }
10319             return null;
10320         }
10321     }
10322 
10323     @Override
getNamesForUids(int[] uids)10324     public String[] getNamesForUids(int[] uids) {
10325         if (uids == null || uids.length == 0) {
10326             return null;
10327         }
10328         final int callingUid = Binder.getCallingUid();
10329         if (getInstantAppPackageName(callingUid) != null) {
10330             return null;
10331         }
10332         final int callingUserId = UserHandle.getUserId(callingUid);
10333         final String[] names = new String[uids.length];
10334         synchronized (mLock) {
10335             for (int i = uids.length - 1; i >= 0; i--) {
10336                 final int appId = UserHandle.getAppId(uids[i]);
10337                 final Object obj = mSettings.getSettingLPr(appId);
10338                 if (obj instanceof SharedUserSetting) {
10339                     final SharedUserSetting sus = (SharedUserSetting) obj;
10340                     if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10341                         names[i] = null;
10342                     } else {
10343                         names[i] = "shared:" + sus.name;
10344                     }
10345                 } else if (obj instanceof PackageSetting) {
10346                     final PackageSetting ps = (PackageSetting) obj;
10347                     if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10348                         names[i] = null;
10349                     } else {
10350                         names[i] = ps.name;
10351                     }
10352                 } else {
10353                     names[i] = null;
10354                 }
10355             }
10356         }
10357         return names;
10358     }
10359 
10360     @Override
getUidForSharedUser(String sharedUserName)10361     public int getUidForSharedUser(String sharedUserName) {
10362         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10363             return -1;
10364         }
10365         if (sharedUserName == null) {
10366             return -1;
10367         }
10368         // reader
10369         synchronized (mLock) {
10370             SharedUserSetting suid;
10371             try {
10372                 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
10373                 if (suid != null) {
10374                     return suid.userId;
10375                 }
10376             } catch (PackageManagerException ignore) {
10377                 // can't happen, but, still need to catch it
10378             }
10379             return -1;
10380         }
10381     }
10382 
10383     @Override
getFlagsForUid(int uid)10384     public int getFlagsForUid(int uid) {
10385         final int callingUid = Binder.getCallingUid();
10386         if (getInstantAppPackageName(callingUid) != null) {
10387             return 0;
10388         }
10389         final int callingUserId = UserHandle.getUserId(callingUid);
10390         final int appId = UserHandle.getAppId(uid);
10391         synchronized (mLock) {
10392             final Object obj = mSettings.getSettingLPr(appId);
10393             if (obj instanceof SharedUserSetting) {
10394                 final SharedUserSetting sus = (SharedUserSetting) obj;
10395                 if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10396                     return 0;
10397                 }
10398                 return sus.pkgFlags;
10399             } else if (obj instanceof PackageSetting) {
10400                 final PackageSetting ps = (PackageSetting) obj;
10401                 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10402                     return 0;
10403                 }
10404                 return ps.pkgFlags;
10405             }
10406         }
10407         return 0;
10408     }
10409 
10410     @Override
getPrivateFlagsForUid(int uid)10411     public int getPrivateFlagsForUid(int uid) {
10412         final int callingUid = Binder.getCallingUid();
10413         if (getInstantAppPackageName(callingUid) != null) {
10414             return 0;
10415         }
10416         final int callingUserId = UserHandle.getUserId(callingUid);
10417         final int appId = UserHandle.getAppId(uid);
10418         synchronized (mLock) {
10419             final Object obj = mSettings.getSettingLPr(appId);
10420             if (obj instanceof SharedUserSetting) {
10421                 final SharedUserSetting sus = (SharedUserSetting) obj;
10422                 if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10423                     return 0;
10424                 }
10425                 return sus.pkgPrivateFlags;
10426             } else if (obj instanceof PackageSetting) {
10427                 final PackageSetting ps = (PackageSetting) obj;
10428                 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10429                     return 0;
10430                 }
10431                 return ps.pkgPrivateFlags;
10432             }
10433         }
10434         return 0;
10435     }
10436 
10437     @Override
isUidPrivileged(int uid)10438     public boolean isUidPrivileged(int uid) {
10439         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10440             return false;
10441         }
10442         final int appId = UserHandle.getAppId(uid);
10443         // reader
10444         synchronized (mLock) {
10445             final Object obj = mSettings.getSettingLPr(appId);
10446             if (obj instanceof SharedUserSetting) {
10447                 final SharedUserSetting sus = (SharedUserSetting) obj;
10448                 final int numPackages = sus.packages.size();
10449                 for (int index = 0; index < numPackages; index++) {
10450                     final PackageSetting ps = sus.packages.valueAt(index);
10451                     if (ps.isPrivileged()) {
10452                         return true;
10453                     }
10454                 }
10455             } else if (obj instanceof PackageSetting) {
10456                 final PackageSetting ps = (PackageSetting) obj;
10457                 return ps.isPrivileged();
10458             }
10459         }
10460         return false;
10461     }
10462 
10463     // NOTE: Can't remove due to unsupported app usage
10464     @NonNull
10465     @Override
getAppOpPermissionPackages(String permissionName)10466     public String[] getAppOpPermissionPackages(String permissionName) {
10467         if (permissionName == null) {
10468             return EmptyArray.STRING;
10469         }
10470         if (getInstantAppPackageName(getCallingUid()) != null) {
10471             return EmptyArray.STRING;
10472         }
10473         return mPermissionManager.getAppOpPermissionPackages(permissionName);
10474     }
10475 
10476     @Override
resolveIntent(Intent intent, String resolvedType, int flags, int userId)10477     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
10478             int flags, int userId) {
10479         return resolveIntentInternal(intent, resolvedType, flags, 0 /*privateResolveFlags*/,
10480                 userId, false, Binder.getCallingUid());
10481     }
10482 
10483     /**
10484      * Normally instant apps can only be resolved when they're visible to the caller.
10485      * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
10486      * since we need to allow the system to start any installed application.
10487      */
resolveIntentInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int userId, boolean resolveForStart, int filterCallingUid)10488     private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType, int flags,
10489             @PrivateResolveFlags int privateResolveFlags, int userId, boolean resolveForStart,
10490             int filterCallingUid) {
10491         try {
10492             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
10493 
10494             if (!mUserManager.exists(userId)) return null;
10495             final int callingUid = Binder.getCallingUid();
10496             flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
10497                     isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
10498                             flags));
10499             enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
10500                     false /*checkShell*/, "resolve intent");
10501 
10502             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
10503             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
10504                     flags, privateResolveFlags, filterCallingUid, userId, resolveForStart,
10505                     true /*allowDynamicSplits*/);
10506             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10507 
10508             final boolean queryMayBeFiltered =
10509                     UserHandle.getAppId(filterCallingUid) >= Process.FIRST_APPLICATION_UID
10510                             && !resolveForStart;
10511 
10512             final ResolveInfo bestChoice =
10513                     chooseBestActivity(
10514                             intent, resolvedType, flags, privateResolveFlags, query, userId,
10515                             queryMayBeFiltered);
10516             final boolean nonBrowserOnly =
10517                     (privateResolveFlags & PackageManagerInternal.RESOLVE_NON_BROWSER_ONLY) != 0;
10518             if (nonBrowserOnly && bestChoice != null && bestChoice.handleAllWebDataURI) {
10519                 return null;
10520             }
10521             return bestChoice;
10522         } finally {
10523             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10524         }
10525     }
10526 
10527     @Override
findPersistentPreferredActivity(Intent intent, int userId)10528     public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
10529         if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
10530             throw new SecurityException(
10531                     "findPersistentPreferredActivity can only be run by the system");
10532         }
10533         if (!mUserManager.exists(userId)) {
10534             return null;
10535         }
10536         final int callingUid = Binder.getCallingUid();
10537         intent = updateIntentForResolve(intent);
10538         final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
10539         final int flags = updateFlagsForResolve(
10540                 0, userId, callingUid, false /*includeInstantApps*/,
10541                 isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType, 0));
10542         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
10543                 userId);
10544         synchronized (mLock) {
10545             return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
10546                     userId);
10547         }
10548     }
10549 
10550     @Override
setLastChosenActivity(Intent intent, String resolvedType, int flags, IntentFilter filter, int match, ComponentName activity)10551     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
10552             IntentFilter filter, int match, ComponentName activity) {
10553         setLastChosenActivity(intent, resolvedType, flags,
10554                               new WatchedIntentFilter(filter), match, activity);
10555     }
10556 
10557     /**
10558      * Variant that takes a {@link WatchedIntentFilter}
10559      */
setLastChosenActivity(Intent intent, String resolvedType, int flags, WatchedIntentFilter filter, int match, ComponentName activity)10560     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
10561             WatchedIntentFilter filter, int match, ComponentName activity) {
10562         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10563             return;
10564         }
10565         final int userId = UserHandle.getCallingUserId();
10566         if (DEBUG_PREFERRED) {
10567             Log.v(TAG, "setLastChosenActivity intent=" + intent
10568                 + " resolvedType=" + resolvedType
10569                 + " flags=" + flags
10570                 + " filter=" + filter
10571                 + " match=" + match
10572                 + " activity=" + activity);
10573             filter.dump(new PrintStreamPrinter(System.out), "    ");
10574         }
10575         intent.setComponent(null);
10576         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
10577                 userId);
10578         // Find any earlier preferred or last chosen entries and nuke them
10579         findPreferredActivityNotLocked(
10580                 intent, resolvedType, flags, query, 0, false, true, false, userId);
10581         // Add the new activity as the last chosen for this filter
10582         addPreferredActivity(filter, match, null, activity, false, userId,
10583                 "Setting last chosen", false);
10584     }
10585 
10586     @Override
getLastChosenActivity(Intent intent, String resolvedType, int flags)10587     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
10588         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10589             return null;
10590         }
10591         final int userId = UserHandle.getCallingUserId();
10592         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
10593         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
10594                 userId);
10595         return findPreferredActivityNotLocked(
10596                 intent, resolvedType, flags, query, 0, false, false, false, userId);
10597     }
10598 
requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, Intent origIntent, String resolvedType, String callingPackage, @Nullable String callingFeatureId, boolean isRequesterInstantApp, Bundle verificationBundle, int userId)10599     private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
10600             Intent origIntent, String resolvedType, String callingPackage,
10601             @Nullable String callingFeatureId, boolean isRequesterInstantApp,
10602             Bundle verificationBundle, int userId) {
10603         final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
10604                 new InstantAppRequest(responseObj, origIntent, resolvedType,
10605                         callingPackage, callingFeatureId, isRequesterInstantApp, userId, verificationBundle,
10606                         false /*resolveForStart*/, responseObj.hostDigestPrefixSecure,
10607                         responseObj.token));
10608         mHandler.sendMessage(msg);
10609     }
10610 
chooseBestActivity(Intent intent, String resolvedType, int flags, int privateResolveFlags, List<ResolveInfo> query, int userId, boolean queryMayBeFiltered)10611     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
10612             int flags, int privateResolveFlags, List<ResolveInfo> query, int userId,
10613             boolean queryMayBeFiltered) {
10614         if (query != null) {
10615             final int N = query.size();
10616             if (N == 1) {
10617                 return query.get(0);
10618             } else if (N > 1) {
10619                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
10620                 // If there is more than one activity with the same priority,
10621                 // then let the user decide between them.
10622                 ResolveInfo r0 = query.get(0);
10623                 ResolveInfo r1 = query.get(1);
10624                 if (DEBUG_INTENT_MATCHING || debug) {
10625                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
10626                             + r1.activityInfo.name + "=" + r1.priority);
10627                 }
10628                 // If the first activity has a higher priority, or a different
10629                 // default, then it is always desirable to pick it.
10630                 if (r0.priority != r1.priority
10631                         || r0.preferredOrder != r1.preferredOrder
10632                         || r0.isDefault != r1.isDefault) {
10633                     return query.get(0);
10634                 }
10635                 // If we have saved a preference for a preferred activity for
10636                 // this Intent, use that.
10637                 ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
10638                         flags, query, r0.priority, true, false, debug, userId, queryMayBeFiltered);
10639                 if (ri != null) {
10640                     return ri;
10641                 }
10642                 int browserCount = 0;
10643                 for (int i = 0; i < N; i++) {
10644                     ri = query.get(i);
10645                     if (ri.handleAllWebDataURI) {
10646                         browserCount++;
10647                     }
10648                     // If we have an ephemeral app, use it
10649                     if (ri.activityInfo.applicationInfo.isInstantApp()) {
10650                         final String packageName = ri.activityInfo.packageName;
10651                         final PackageSetting ps = mSettings.getPackageLPr(packageName);
10652                         if (ps != null && hasAnyDomainApproval(mDomainVerificationManager, ps,
10653                                 intent, flags, userId)) {
10654                             return ri;
10655                         }
10656                     }
10657                 }
10658                 if ((privateResolveFlags
10659                         & PackageManagerInternal.RESOLVE_NON_RESOLVER_ONLY) != 0) {
10660                     return null;
10661                 }
10662                 ri = new ResolveInfo(mResolveInfo);
10663                 // if all resolve options are browsers, mark the resolver's info as if it were
10664                 // also a browser.
10665                 ri.handleAllWebDataURI = browserCount == N;
10666                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
10667                 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
10668                 // If all of the options come from the same package, show the application's
10669                 // label and icon instead of the generic resolver's.
10670                 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
10671                 // and then throw away the ResolveInfo itself, meaning that the caller loses
10672                 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
10673                 // a fallback for this case; we only set the target package's resources on
10674                 // the ResolveInfo, not the ActivityInfo.
10675                 final String intentPackage = intent.getPackage();
10676                 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
10677                     final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
10678                     ri.resolvePackageName = intentPackage;
10679                     if (userNeedsBadging(userId)) {
10680                         ri.noResourceId = true;
10681                     } else {
10682                         ri.icon = appi.icon;
10683                     }
10684                     ri.iconResourceId = appi.icon;
10685                     ri.labelRes = appi.labelRes;
10686                 }
10687                 ri.activityInfo.applicationInfo = new ApplicationInfo(
10688                         ri.activityInfo.applicationInfo);
10689                 if (userId != 0) {
10690                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
10691                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
10692                 }
10693                 // Make sure that the resolver is displayable in car mode
10694                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
10695                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
10696                 return ri;
10697             }
10698         }
10699         return null;
10700     }
10701 
10702     /**
10703      * Do NOT use for intent resolution filtering. That should be done with
10704      * {@link DomainVerificationManagerInternal#filterToApprovedApp(Intent, List, int, Function)}.
10705      *
10706      * @return if the package is approved at any non-zero level for the domain in the intent
10707      */
hasAnyDomainApproval( @onNull DomainVerificationManagerInternal manager, @NonNull PackageSetting pkgSetting, @NonNull Intent intent, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId)10708     private static boolean hasAnyDomainApproval(
10709             @NonNull DomainVerificationManagerInternal manager, @NonNull PackageSetting pkgSetting,
10710             @NonNull Intent intent, @PackageManager.ResolveInfoFlags int resolveInfoFlags,
10711             @UserIdInt int userId) {
10712         return manager.approvalLevelForDomain(pkgSetting, intent, resolveInfoFlags, userId)
10713                 > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE;
10714     }
10715 
10716     /**
10717      * Return true if the given list is not empty and all of its contents have
10718      * an activityInfo with the given package name.
10719      */
allHavePackage(List<ResolveInfo> list, String packageName)10720     private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
10721         if (ArrayUtils.isEmpty(list)) {
10722             return false;
10723         }
10724         for (int i = 0, N = list.size(); i < N; i++) {
10725             final ResolveInfo ri = list.get(i);
10726             final ActivityInfo ai = ri != null ? ri.activityInfo : null;
10727             if (ai == null || !packageName.equals(ai.packageName)) {
10728                 return false;
10729             }
10730         }
10731         return true;
10732     }
10733 
10734     /**
10735      * From Android R, camera intents have to match system apps. The only exception to this is if
10736      * the DPC has set the camera persistent preferred activity. This case was introduced
10737      * because it is important that the DPC has the ability to set both system and non-system
10738      * camera persistent preferred activities.
10739      *
10740      * @return {@code true} if the intent is a camera intent and the persistent preferred
10741      * activity was not set by the DPC.
10742      */
10743     @GuardedBy("mLock")
isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, String resolvedType, int flags)10744     private boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
10745             String resolvedType, int flags) {
10746         return mComputer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
10747                 resolvedType, flags);
10748     }
10749 
10750     @GuardedBy("mLock")
findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)10751     private ResolveInfo findPersistentPreferredActivityLP(Intent intent,
10752             String resolvedType,
10753             int flags, List<ResolveInfo> query, boolean debug, int userId) {
10754         return mComputer.findPersistentPreferredActivityLP(intent,
10755                 resolvedType,
10756                 flags, query, debug, userId);
10757     }
10758 
isHomeIntent(Intent intent)10759     private static boolean isHomeIntent(Intent intent) {
10760         return ACTION_MAIN.equals(intent.getAction())
10761                 && intent.hasCategory(CATEGORY_HOME)
10762                 && intent.hasCategory(CATEGORY_DEFAULT);
10763     }
10764 
10765 
10766     // findPreferredActivityBody returns two items: a "things changed" flag and a
10767     // ResolveInfo, which is the preferred activity itself.
10768     private static class FindPreferredActivityBodyResult {
10769         boolean mChanged;
10770         ResolveInfo mPreferredResolveInfo;
10771     }
10772 
findPreferredActivityInternal( Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered)10773     private FindPreferredActivityBodyResult findPreferredActivityInternal(
10774             Intent intent, String resolvedType, int flags,
10775             List<ResolveInfo> query, boolean always,
10776             boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
10777         return mComputer.findPreferredActivityInternal(
10778             intent, resolvedType, flags,
10779             query, always,
10780             removeMatches, debug, userId, queryMayBeFiltered);
10781     }
10782 
findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId)10783     ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
10784             List<ResolveInfo> query, int priority, boolean always,
10785             boolean removeMatches, boolean debug, int userId) {
10786         return findPreferredActivityNotLocked(
10787                 intent, resolvedType, flags, query, priority, always, removeMatches, debug, userId,
10788                 UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID);
10789     }
10790 
10791     // TODO: handle preferred activities missing while user has amnesia
10792     /** <b>must not hold {@link #mLock}</b> */
findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered)10793     ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
10794             List<ResolveInfo> query, int priority, boolean always,
10795             boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
10796         if (Thread.holdsLock(mLock)) {
10797             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
10798                     + " is holding mLock", new Throwable());
10799         }
10800         if (!mUserManager.exists(userId)) return null;
10801 
10802         FindPreferredActivityBodyResult body = findPreferredActivityInternal(
10803                 intent, resolvedType, flags, query, always,
10804                 removeMatches, debug, userId, queryMayBeFiltered);
10805         if (body.mChanged) {
10806             if (DEBUG_PREFERRED) {
10807                 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
10808             }
10809             synchronized (mLock) {
10810                 scheduleWritePackageRestrictionsLocked(userId);
10811             }
10812         }
10813         if ((DEBUG_PREFERRED || debug) && body.mPreferredResolveInfo == null) {
10814             Slog.v(TAG, "No preferred activity to return");
10815         }
10816         return body.mPreferredResolveInfo;
10817     }
10818 
10819     /*
10820      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
10821      */
10822     @Override
canForwardTo(Intent intent, String resolvedType, int sourceUserId, int targetUserId)10823     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
10824             int targetUserId) {
10825         mContext.enforceCallingOrSelfPermission(
10826                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
10827         List<CrossProfileIntentFilter> matches =
10828                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
10829         if (matches != null) {
10830             int size = matches.size();
10831             for (int i = 0; i < size; i++) {
10832                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
10833             }
10834         }
10835         if (intent.hasWebURI()) {
10836             // cross-profile app linking works only towards the parent.
10837             final int callingUid = Binder.getCallingUid();
10838             final UserInfo parent = getProfileParent(sourceUserId);
10839             if (parent == null) {
10840                 return false;
10841             }
10842             synchronized (mLock) {
10843                 int flags = updateFlagsForResolve(0, parent.id, callingUid,
10844                         false /*includeInstantApps*/,
10845                         isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, parent.id,
10846                                 resolvedType, 0));
10847                 flags |= PackageManager.MATCH_DEFAULT_ONLY;
10848                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
10849                         intent, resolvedType, flags, sourceUserId, parent.id);
10850                 return xpDomainInfo != null;
10851             }
10852         }
10853         return false;
10854     }
10855 
getProfileParent(int userId)10856     private UserInfo getProfileParent(int userId) {
10857         return mComputer.getProfileParent(userId);
10858     }
10859 
getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId)10860     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
10861             String resolvedType, int userId) {
10862         return mComputer.getMatchingCrossProfileIntentFilters(intent,
10863                 resolvedType, userId);
10864     }
10865 
10866     @Override
queryIntentActivities(Intent intent, String resolvedType, int flags, int userId)10867     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
10868             String resolvedType, int flags, int userId) {
10869         try {
10870             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
10871 
10872             return new ParceledListSlice<>(
10873                     queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
10874         } finally {
10875             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10876         }
10877     }
10878 
10879     /**
10880      * Returns the package name of the calling Uid if it's an instant app. If it isn't
10881      * instant, returns {@code null}.
10882      */
getInstantAppPackageName(int callingUid)10883     private String getInstantAppPackageName(int callingUid) {
10884         return mComputer.getInstantAppPackageName(callingUid);
10885     }
10886 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId)10887     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
10888             String resolvedType, int flags, int userId) {
10889         return mComputer.queryIntentActivitiesInternal(intent,
10890                 resolvedType, flags, userId);
10891     }
10892 
10893     // Collect the results of queryIntentActivitiesInternalBody into a single class
10894     private static class QueryIntentActivitiesResult {
10895         public boolean sortResult = false;
10896         public boolean addInstant = false;
10897         public List<ResolveInfo> result = null;
10898         public List<ResolveInfo> answer = null;
10899 
QueryIntentActivitiesResult(List<ResolveInfo> l)10900         QueryIntentActivitiesResult(List<ResolveInfo> l) {
10901             answer = l;
10902         }
QueryIntentActivitiesResult(boolean s, boolean a, List<ResolveInfo> l)10903         QueryIntentActivitiesResult(boolean s, boolean a, List<ResolveInfo> l) {
10904             sortResult = s;
10905             addInstant = a;
10906             result = l;
10907         }
10908     }
10909 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits)10910     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
10911             String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
10912             int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits) {
10913         return mComputer.queryIntentActivitiesInternal(intent,
10914                 resolvedType, flags, privateResolveFlags,
10915                 filterCallingUid, userId, resolveForStart, allowDynamicSplits);
10916     }
10917 
queryIntentActivitiesInternalBody( Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)10918     private @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
10919             Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
10920             boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
10921             String instantAppPkgName) {
10922         return mComputer.queryIntentActivitiesInternalBody(
10923             intent, resolvedType, flags, filterCallingUid, userId,
10924             resolveForStart, allowDynamicSplits, pkgName,
10925             instantAppPkgName);
10926     }
10927 
10928     private static class CrossProfileDomainInfo {
10929         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
10930         ResolveInfo resolveInfo;
10931         int highestApprovalLevel;
10932 
CrossProfileDomainInfo(ResolveInfo resolveInfo, int highestApprovalLevel)10933         CrossProfileDomainInfo(ResolveInfo resolveInfo, int highestApprovalLevel) {
10934             this.resolveInfo = resolveInfo;
10935             this.highestApprovalLevel = highestApprovalLevel;
10936         }
10937 
10938         @Override
toString()10939         public String toString() {
10940             return "CrossProfileDomainInfo{"
10941                     + "resolveInfo=" + resolveInfo
10942                     + ", highestApprovalLevel=" + highestApprovalLevel
10943                     + '}';
10944         }
10945     }
10946 
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)10947     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
10948             String resolvedType, int flags, int sourceUserId, int parentUserId) {
10949         return mComputer.getCrossProfileDomainPreferredLpr(intent,
10950                 resolvedType, flags, sourceUserId, parentUserId);
10951     }
10952 
10953     /**
10954      * Filters out ephemeral activities.
10955      * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
10956      * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
10957      *
10958      * @param resolveInfos The pre-filtered list of resolved activities
10959      * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
10960      *          is performed.
10961      * @param intent
10962      * @return A filtered list of resolved activities.
10963      */
applyPostResolutionFilter(@onNull List<ResolveInfo> resolveInfos, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, boolean resolveForStart, int userId, Intent intent)10964     private List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
10965             String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
10966             boolean resolveForStart, int userId, Intent intent) {
10967         return mComputer.applyPostResolutionFilter(resolveInfos,
10968                 ephemeralPkgName, allowDynamicSplits, filterCallingUid,
10969                 resolveForStart, userId, intent);
10970     }
10971 
10972     @Override
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)10973     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
10974             Intent[] specifics, String[] specificTypes, Intent intent,
10975             String resolvedType, int flags, int userId) {
10976         return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
10977                 specificTypes, intent, resolvedType, flags, userId));
10978     }
10979 
queryIntentActivityOptionsInternal(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)10980     private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
10981             Intent[] specifics, String[] specificTypes, Intent intent,
10982             String resolvedType, int flags, int userId) {
10983         if (!mUserManager.exists(userId)) return Collections.emptyList();
10984         final int callingUid = Binder.getCallingUid();
10985         flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
10986                 isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
10987                         flags));
10988         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
10989                 false /*checkShell*/, "query intent activity options");
10990         final String resultsAction = intent.getAction();
10991 
10992         final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
10993                 | PackageManager.GET_RESOLVED_FILTER, userId);
10994 
10995         if (DEBUG_INTENT_MATCHING) {
10996             Log.v(TAG, "Query " + intent + ": " + results);
10997         }
10998 
10999         int specificsPos = 0;
11000         int N;
11001 
11002         // todo: note that the algorithm used here is O(N^2).  This
11003         // isn't a problem in our current environment, but if we start running
11004         // into situations where we have more than 5 or 10 matches then this
11005         // should probably be changed to something smarter...
11006 
11007         // First we go through and resolve each of the specific items
11008         // that were supplied, taking care of removing any corresponding
11009         // duplicate items in the generic resolve list.
11010         if (specifics != null) {
11011             for (int i=0; i<specifics.length; i++) {
11012                 final Intent sintent = specifics[i];
11013                 if (sintent == null) {
11014                     continue;
11015                 }
11016 
11017                 if (DEBUG_INTENT_MATCHING) {
11018                     Log.v(TAG, "Specific #" + i + ": " + sintent);
11019                 }
11020 
11021                 String action = sintent.getAction();
11022                 if (resultsAction != null && resultsAction.equals(action)) {
11023                     // If this action was explicitly requested, then don't
11024                     // remove things that have it.
11025                     action = null;
11026                 }
11027 
11028                 ResolveInfo ri = null;
11029                 ActivityInfo ai = null;
11030 
11031                 ComponentName comp = sintent.getComponent();
11032                 if (comp == null) {
11033                     ri = resolveIntent(
11034                         sintent,
11035                         specificTypes != null ? specificTypes[i] : null,
11036                             flags, userId);
11037                     if (ri == null) {
11038                         continue;
11039                     }
11040                     if (ri == mResolveInfo) {
11041                         // ACK!  Must do something better with this.
11042                     }
11043                     ai = ri.activityInfo;
11044                     comp = new ComponentName(ai.applicationInfo.packageName,
11045                             ai.name);
11046                 } else {
11047                     ai = getActivityInfo(comp, flags, userId);
11048                     if (ai == null) {
11049                         continue;
11050                     }
11051                 }
11052 
11053                 // Look for any generic query activities that are duplicates
11054                 // of this specific one, and remove them from the results.
11055                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
11056                 N = results.size();
11057                 int j;
11058                 for (j=specificsPos; j<N; j++) {
11059                     ResolveInfo sri = results.get(j);
11060                     if ((sri.activityInfo.name.equals(comp.getClassName())
11061                             && sri.activityInfo.applicationInfo.packageName.equals(
11062                                     comp.getPackageName()))
11063                         || (action != null && sri.filter.matchAction(action))) {
11064                         results.remove(j);
11065                         if (DEBUG_INTENT_MATCHING) Log.v(
11066                             TAG, "Removing duplicate item from " + j
11067                             + " due to specific " + specificsPos);
11068                         if (ri == null) {
11069                             ri = sri;
11070                         }
11071                         j--;
11072                         N--;
11073                     }
11074                 }
11075 
11076                 // Add this specific item to its proper place.
11077                 if (ri == null) {
11078                     ri = new ResolveInfo();
11079                     ri.activityInfo = ai;
11080                 }
11081                 results.add(specificsPos, ri);
11082                 ri.specificIndex = i;
11083                 specificsPos++;
11084             }
11085         }
11086 
11087         // Now we go through the remaining generic results and remove any
11088         // duplicate actions that are found here.
11089         N = results.size();
11090         for (int i=specificsPos; i<N-1; i++) {
11091             final ResolveInfo rii = results.get(i);
11092             if (rii.filter == null) {
11093                 continue;
11094             }
11095 
11096             // Iterate over all of the actions of this result's intent
11097             // filter...  typically this should be just one.
11098             final Iterator<String> it = rii.filter.actionsIterator();
11099             if (it == null) {
11100                 continue;
11101             }
11102             while (it.hasNext()) {
11103                 final String action = it.next();
11104                 if (resultsAction != null && resultsAction.equals(action)) {
11105                     // If this action was explicitly requested, then don't
11106                     // remove things that have it.
11107                     continue;
11108                 }
11109                 for (int j=i+1; j<N; j++) {
11110                     final ResolveInfo rij = results.get(j);
11111                     if (rij.filter != null && rij.filter.hasAction(action)) {
11112                         results.remove(j);
11113                         if (DEBUG_INTENT_MATCHING) Log.v(
11114                             TAG, "Removing duplicate item from " + j
11115                             + " due to action " + action + " at " + i);
11116                         j--;
11117                         N--;
11118                     }
11119                 }
11120             }
11121 
11122             // If the caller didn't request filter information, drop it now
11123             // so we don't have to marshall/unmarshall it.
11124             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
11125                 rii.filter = null;
11126             }
11127         }
11128 
11129         // Filter out the caller activity if so requested.
11130         if (caller != null) {
11131             N = results.size();
11132             for (int i=0; i<N; i++) {
11133                 ActivityInfo ainfo = results.get(i).activityInfo;
11134                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
11135                         && caller.getClassName().equals(ainfo.name)) {
11136                     results.remove(i);
11137                     break;
11138                 }
11139             }
11140         }
11141 
11142         // If the caller didn't request filter information,
11143         // drop them now so we don't have to
11144         // marshall/unmarshall it.
11145         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
11146             N = results.size();
11147             for (int i=0; i<N; i++) {
11148                 results.get(i).filter = null;
11149             }
11150         }
11151 
11152         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
11153         return results;
11154     }
11155 
11156     @Override
queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)11157     public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
11158             String resolvedType, int flags, int userId) {
11159         return new ParceledListSlice<>(
11160                 queryIntentReceiversInternal(intent, resolvedType, flags, userId,
11161                         false /*allowDynamicSplits*/));
11162     }
11163 
queryIntentReceiversInternal(Intent intent, String resolvedType, int flags, int userId, boolean allowDynamicSplits)11164     private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
11165             String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
11166         if (!mUserManager.exists(userId)) return Collections.emptyList();
11167         final int callingUid = Binder.getCallingUid();
11168         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
11169                 false /*checkShell*/, "query intent receivers");
11170         final String instantAppPkgName = getInstantAppPackageName(callingUid);
11171         flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
11172                 isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
11173                         flags));
11174         ComponentName comp = intent.getComponent();
11175         if (comp == null) {
11176             if (intent.getSelector() != null) {
11177                 intent = intent.getSelector();
11178                 comp = intent.getComponent();
11179             }
11180         }
11181         if (comp != null) {
11182             final List<ResolveInfo> list = new ArrayList<>(1);
11183             final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
11184             if (ai != null) {
11185                 // When specifying an explicit component, we prevent the activity from being
11186                 // used when either 1) the calling package is normal and the activity is within
11187                 // an instant application or 2) the calling package is ephemeral and the
11188                 // activity is not visible to instant applications.
11189                 final boolean matchInstantApp =
11190                         (flags & PackageManager.MATCH_INSTANT) != 0;
11191                 final boolean matchVisibleToInstantAppOnly =
11192                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
11193                 final boolean matchExplicitlyVisibleOnly =
11194                         (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
11195                 final boolean isCallerInstantApp =
11196                         instantAppPkgName != null;
11197                 final boolean isTargetSameInstantApp =
11198                         comp.getPackageName().equals(instantAppPkgName);
11199                 final boolean isTargetInstantApp =
11200                         (ai.applicationInfo.privateFlags
11201                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
11202                 final boolean isTargetVisibleToInstantApp =
11203                         (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
11204                 final boolean isTargetExplicitlyVisibleToInstantApp =
11205                         isTargetVisibleToInstantApp
11206                         && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
11207                 final boolean isTargetHiddenFromInstantApp =
11208                         !isTargetVisibleToInstantApp
11209                         || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
11210                 final boolean blockResolution =
11211                         !isTargetSameInstantApp
11212                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
11213                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
11214                                         && isTargetHiddenFromInstantApp));
11215                 if (!blockResolution) {
11216                     ResolveInfo ri = new ResolveInfo();
11217                     ri.activityInfo = ai;
11218                     list.add(ri);
11219                 }
11220             }
11221             return applyPostResolutionFilter(
11222                     list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
11223                     intent);
11224         }
11225 
11226         // reader
11227         synchronized (mLock) {
11228             String pkgName = intent.getPackage();
11229             if (pkgName == null) {
11230                 final List<ResolveInfo> result =
11231                         mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
11232                 if (result == null) {
11233                     return Collections.emptyList();
11234                 }
11235                 return applyPostResolutionFilter(
11236                         result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
11237                         intent);
11238             }
11239             final AndroidPackage pkg = mPackages.get(pkgName);
11240             if (pkg != null) {
11241                 final List<ResolveInfo> result = mComponentResolver.queryReceivers(
11242                         intent, resolvedType, flags, pkg.getReceivers(), userId);
11243                 if (result == null) {
11244                     return Collections.emptyList();
11245                 }
11246                 return applyPostResolutionFilter(
11247                         result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
11248                         intent);
11249             }
11250             return Collections.emptyList();
11251         }
11252     }
11253 
11254     @Override
resolveService(Intent intent, String resolvedType, int flags, int userId)11255     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
11256         final int callingUid = Binder.getCallingUid();
11257         return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
11258     }
11259 
resolveServiceInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid)11260     private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
11261             int userId, int callingUid) {
11262         if (!mUserManager.exists(userId)) return null;
11263         flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
11264                 false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
11265         List<ResolveInfo> query = queryIntentServicesInternal(
11266                 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
11267         if (query != null) {
11268             if (query.size() >= 1) {
11269                 // If there is more than one service with the same priority,
11270                 // just arbitrarily pick the first one.
11271                 return query.get(0);
11272             }
11273         }
11274         return null;
11275     }
11276 
11277     @Override
queryIntentServices(Intent intent, String resolvedType, int flags, int userId)11278     public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
11279             String resolvedType, int flags, int userId) {
11280         final int callingUid = Binder.getCallingUid();
11281         return new ParceledListSlice<>(queryIntentServicesInternal(
11282                 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
11283     }
11284 
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps)11285     private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
11286             String resolvedType, int flags, int userId, int callingUid,
11287             boolean includeInstantApps) {
11288         return mComputer.queryIntentServicesInternal(intent,
11289                 resolvedType, flags, userId, callingUid,
11290                 includeInstantApps);
11291     }
11292 
11293     @Override
queryIntentContentProviders(Intent intent, String resolvedType, int flags, int userId)11294     public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
11295             String resolvedType, int flags, int userId) {
11296         return new ParceledListSlice<>(
11297                 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
11298     }
11299 
queryIntentContentProvidersInternal( Intent intent, String resolvedType, int flags, int userId)11300     private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
11301             Intent intent, String resolvedType, int flags, int userId) {
11302         if (!mUserManager.exists(userId)) return Collections.emptyList();
11303         final int callingUid = Binder.getCallingUid();
11304         final String instantAppPkgName = getInstantAppPackageName(callingUid);
11305         flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
11306                 false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
11307         ComponentName comp = intent.getComponent();
11308         if (comp == null) {
11309             if (intent.getSelector() != null) {
11310                 intent = intent.getSelector();
11311                 comp = intent.getComponent();
11312             }
11313         }
11314         if (comp != null) {
11315             final List<ResolveInfo> list = new ArrayList<>(1);
11316             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
11317             if (pi != null) {
11318                 // When specifying an explicit component, we prevent the provider from being
11319                 // used when either 1) the provider is in an instant application and the
11320                 // caller is not the same instant application or 2) the calling package is an
11321                 // instant application and the provider is not visible to instant applications.
11322                 final boolean matchInstantApp =
11323                         (flags & PackageManager.MATCH_INSTANT) != 0;
11324                 final boolean matchVisibleToInstantAppOnly =
11325                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
11326                 final boolean isCallerInstantApp =
11327                         instantAppPkgName != null;
11328                 final boolean isTargetSameInstantApp =
11329                         comp.getPackageName().equals(instantAppPkgName);
11330                 final boolean isTargetInstantApp =
11331                         (pi.applicationInfo.privateFlags
11332                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
11333                 final boolean isTargetHiddenFromInstantApp =
11334                         (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
11335                 final boolean blockResolution =
11336                         !isTargetSameInstantApp
11337                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
11338                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
11339                                         && isTargetHiddenFromInstantApp));
11340                 final boolean blockNormalResolution = !isTargetInstantApp && !isCallerInstantApp
11341                         && shouldFilterApplicationLocked(
11342                         getPackageSettingInternal(pi.applicationInfo.packageName,
11343                                 Process.SYSTEM_UID), callingUid, userId);
11344                 if (!blockResolution && !blockNormalResolution) {
11345                     final ResolveInfo ri = new ResolveInfo();
11346                     ri.providerInfo = pi;
11347                     list.add(ri);
11348                 }
11349             }
11350             return list;
11351         }
11352 
11353         // reader
11354         synchronized (mLock) {
11355             String pkgName = intent.getPackage();
11356             if (pkgName == null) {
11357                 final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
11358                         resolvedType, flags, userId);
11359                 if (resolveInfos == null) {
11360                     return Collections.emptyList();
11361                 }
11362                 return applyPostContentProviderResolutionFilter(
11363                         resolveInfos, instantAppPkgName, userId, callingUid);
11364             }
11365             final AndroidPackage pkg = mPackages.get(pkgName);
11366             if (pkg != null) {
11367                 final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
11368                         resolvedType, flags,
11369                         pkg.getProviders(), userId);
11370                 if (resolveInfos == null) {
11371                     return Collections.emptyList();
11372                 }
11373                 return applyPostContentProviderResolutionFilter(
11374                         resolveInfos, instantAppPkgName, userId, callingUid);
11375             }
11376             return Collections.emptyList();
11377         }
11378     }
11379 
applyPostContentProviderResolutionFilter( List<ResolveInfo> resolveInfos, String instantAppPkgName, @UserIdInt int userId, int callingUid)11380     private List<ResolveInfo> applyPostContentProviderResolutionFilter(
11381             List<ResolveInfo> resolveInfos, String instantAppPkgName,
11382             @UserIdInt int userId, int callingUid) {
11383         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
11384             final ResolveInfo info = resolveInfos.get(i);
11385 
11386             if (instantAppPkgName == null) {
11387                 SettingBase callingSetting =
11388                         mSettings.getSettingLPr(UserHandle.getAppId(callingUid));
11389                 PackageSetting resolvedSetting =
11390                         getPackageSettingInternal(info.providerInfo.packageName, 0);
11391                 if (!mAppsFilter.shouldFilterApplication(
11392                         callingUid, callingSetting, resolvedSetting, userId)) {
11393                     continue;
11394                 }
11395             }
11396 
11397             final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
11398             // allow providers that are defined in the provided package
11399             if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
11400                 if (info.providerInfo.splitName != null
11401                         && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
11402                                 info.providerInfo.splitName)) {
11403                     if (mInstantAppInstallerActivity == null) {
11404                         if (DEBUG_INSTANT) {
11405                             Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
11406                         }
11407                         resolveInfos.remove(i);
11408                         continue;
11409                     }
11410                     // requested provider is defined in a split that hasn't been installed yet.
11411                     // add the installer to the resolve list
11412                     if (DEBUG_INSTANT) {
11413                         Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
11414                     }
11415                     final ResolveInfo installerInfo = new ResolveInfo(
11416                             mInstantAppInstallerInfo);
11417                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
11418                             null /*failureActivity*/,
11419                             info.providerInfo.packageName,
11420                             info.providerInfo.applicationInfo.longVersionCode,
11421                             info.providerInfo.splitName);
11422                     // add a non-generic filter
11423                     installerInfo.filter = new IntentFilter();
11424                     // load resources from the correct package
11425                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
11426                     resolveInfos.set(i, installerInfo);
11427                 }
11428                 continue;
11429             }
11430             // allow providers that have been explicitly exposed to instant applications
11431             if (!isEphemeralApp
11432                     && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
11433                 continue;
11434             }
11435             resolveInfos.remove(i);
11436         }
11437         return resolveInfos;
11438     }
11439 
11440     @Override
getInstalledPackages(int flags, int userId)11441     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
11442         return mComputer.getInstalledPackages(flags, userId);
11443     }
11444 
addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)11445     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
11446             String[] permissions, boolean[] tmp, int flags, int userId) {
11447         int numMatch = 0;
11448         for (int i=0; i<permissions.length; i++) {
11449             final String permission = permissions[i];
11450             if (checkPermission(permission, ps.name, userId) == PERMISSION_GRANTED) {
11451                 tmp[i] = true;
11452                 numMatch++;
11453             } else {
11454                 tmp[i] = false;
11455             }
11456         }
11457         if (numMatch == 0) {
11458             return;
11459         }
11460         final PackageInfo pi = generatePackageInfo(ps, flags, userId);
11461 
11462         // The above might return null in cases of uninstalled apps or install-state
11463         // skew across users/profiles.
11464         if (pi != null) {
11465             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
11466                 if (numMatch == permissions.length) {
11467                     pi.requestedPermissions = permissions;
11468                 } else {
11469                     pi.requestedPermissions = new String[numMatch];
11470                     numMatch = 0;
11471                     for (int i=0; i<permissions.length; i++) {
11472                         if (tmp[i]) {
11473                             pi.requestedPermissions[numMatch] = permissions[i];
11474                             numMatch++;
11475                         }
11476                     }
11477                 }
11478             }
11479             list.add(pi);
11480         }
11481     }
11482 
11483     @Override
getPackagesHoldingPermissions( String[] permissions, int flags, int userId)11484     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
11485             String[] permissions, int flags, int userId) {
11486         if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
11487         flags = updateFlagsForPackage(flags, userId);
11488         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11489                 false /* checkShell */, "get packages holding permissions");
11490         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
11491 
11492         // writer
11493         synchronized (mLock) {
11494             ArrayList<PackageInfo> list = new ArrayList<>();
11495             boolean[] tmpBools = new boolean[permissions.length];
11496             if (listUninstalled) {
11497                 for (PackageSetting ps : mSettings.getPackagesLocked().values()) {
11498                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
11499                             userId);
11500                 }
11501             } else {
11502                 for (AndroidPackage pkg : mPackages.values()) {
11503                     PackageSetting ps = getPackageSetting(pkg.getPackageName());
11504                     if (ps != null) {
11505                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
11506                                 userId);
11507                     }
11508                 }
11509             }
11510 
11511             return new ParceledListSlice<>(list);
11512         }
11513     }
11514 
11515     @Override
getInstalledApplications(int flags, int userId)11516     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
11517         final int callingUid = Binder.getCallingUid();
11518         return new ParceledListSlice<>(
11519                 getInstalledApplicationsListInternal(flags, userId, callingUid));
11520     }
11521 
getInstalledApplicationsListInternal(int flags, int userId, int callingUid)11522     private List<ApplicationInfo> getInstalledApplicationsListInternal(int flags, int userId,
11523             int callingUid) {
11524         if (getInstantAppPackageName(callingUid) != null) {
11525             return Collections.emptyList();
11526         }
11527         if (!mUserManager.exists(userId)) return Collections.emptyList();
11528         flags = updateFlagsForApplication(flags, userId);
11529         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
11530 
11531         enforceCrossUserPermission(
11532             callingUid,
11533             userId,
11534             false /* requireFullPermission */,
11535             false /* checkShell */,
11536             "get installed application info");
11537 
11538         // writer
11539         synchronized (mLock) {
11540             ArrayList<ApplicationInfo> list;
11541             if (listUninstalled) {
11542                 list = new ArrayList<>(mSettings.getPackagesLocked().size());
11543                 for (PackageSetting ps : mSettings.getPackagesLocked().values()) {
11544                     ApplicationInfo ai;
11545                     int effectiveFlags = flags;
11546                     if (ps.isSystem()) {
11547                         effectiveFlags |= PackageManager.MATCH_ANY_USER;
11548                     }
11549                     if (ps.pkg != null) {
11550                         if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
11551                             continue;
11552                         }
11553                         if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
11554                             continue;
11555                         }
11556                         ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, effectiveFlags,
11557                                 ps.readUserState(userId), userId, ps);
11558                         if (ai != null) {
11559                             ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
11560                         }
11561                     } else {
11562                         // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
11563                         // and already converts to externally visible package name
11564                         ai = generateApplicationInfoFromSettingsLPw(ps.name,
11565                                 effectiveFlags, callingUid, userId);
11566                     }
11567                     if (ai != null) {
11568                         list.add(ai);
11569                     }
11570                 }
11571             } else {
11572                 list = new ArrayList<>(mPackages.size());
11573                 for (AndroidPackage p : mPackages.values()) {
11574                     final PackageSetting ps = getPackageSetting(p.getPackageName());
11575                     if (ps != null) {
11576                         if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
11577                             continue;
11578                         }
11579                         if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
11580                             continue;
11581                         }
11582                         ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
11583                                 ps.readUserState(userId), userId, ps);
11584                         if (ai != null) {
11585                             ai.packageName = resolveExternalPackageNameLPr(p);
11586                             list.add(ai);
11587                         }
11588                     }
11589                 }
11590             }
11591 
11592             return list;
11593         }
11594     }
11595 
11596     @Override
getInstantApps(int userId)11597     public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
11598         if (HIDE_EPHEMERAL_APIS) {
11599             return null;
11600         }
11601         if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
11602             mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
11603                     "getEphemeralApplications");
11604         }
11605         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11606                 false /* checkShell */, "getEphemeralApplications");
11607         synchronized (mLock) {
11608             List<InstantAppInfo> instantApps = mInstantAppRegistry
11609                     .getInstantAppsLPr(userId);
11610             if (instantApps != null) {
11611                 return new ParceledListSlice<>(instantApps);
11612             }
11613         }
11614         return null;
11615     }
11616 
11617     @Override
isInstantApp(String packageName, int userId)11618     public boolean isInstantApp(String packageName, int userId) {
11619         return mComputer.isInstantApp(packageName, userId);
11620     }
11621 
isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid)11622     private boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
11623             int callingUid) {
11624         return mComputer.isInstantAppInternal(packageName, userId,
11625                 callingUid);
11626     }
11627 
11628     @Override
getInstantAppCookie(String packageName, int userId)11629     public byte[] getInstantAppCookie(String packageName, int userId) {
11630         if (HIDE_EPHEMERAL_APIS) {
11631             return null;
11632         }
11633 
11634         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11635                 false /* checkShell */, "getInstantAppCookie");
11636         if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
11637             return null;
11638         }
11639         synchronized (mLock) {
11640             return mInstantAppRegistry.getInstantAppCookieLPw(
11641                     packageName, userId);
11642         }
11643     }
11644 
11645     @Override
setInstantAppCookie(String packageName, byte[] cookie, int userId)11646     public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
11647         if (HIDE_EPHEMERAL_APIS) {
11648             return true;
11649         }
11650 
11651         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11652                 true /* checkShell */, "setInstantAppCookie");
11653         if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
11654             return false;
11655         }
11656         synchronized (mLock) {
11657             return mInstantAppRegistry.setInstantAppCookieLPw(
11658                     packageName, cookie, userId);
11659         }
11660     }
11661 
11662     @Override
getInstantAppIcon(String packageName, int userId)11663     public Bitmap getInstantAppIcon(String packageName, int userId) {
11664         if (HIDE_EPHEMERAL_APIS) {
11665             return null;
11666         }
11667 
11668         if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
11669             mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
11670                     "getInstantAppIcon");
11671         }
11672         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11673                 false /* checkShell */, "getInstantAppIcon");
11674 
11675         synchronized (mLock) {
11676             return mInstantAppRegistry.getInstantAppIconLPw(
11677                     packageName, userId);
11678         }
11679     }
11680 
isCallerSameApp(String packageName, int uid)11681     private boolean isCallerSameApp(String packageName, int uid) {
11682         return mComputer.isCallerSameApp(packageName, uid);
11683     }
11684 
11685     @Override
getPersistentApplications(int flags)11686     public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
11687         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
11688             return ParceledListSlice.emptyList();
11689         }
11690         return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
11691     }
11692 
getPersistentApplicationsInternal(int flags)11693     private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
11694         final ArrayList<ApplicationInfo> finalList = new ArrayList<>();
11695 
11696         // reader
11697         synchronized (mLock) {
11698             final int numPackages = mPackages.size();
11699             final int userId = UserHandle.getCallingUserId();
11700             for (int index = 0; index < numPackages; index++) {
11701                 final AndroidPackage p = mPackages.valueAt(index);
11702 
11703                 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
11704                         && !p.isDirectBootAware();
11705                 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
11706                         && p.isDirectBootAware();
11707 
11708                 if (p.isPersistent()
11709                         && (!mSafeMode || p.isSystem())
11710                         && (matchesUnaware || matchesAware)) {
11711                     PackageSetting ps = mSettings.getPackageLPr(p.getPackageName());
11712                     if (ps != null) {
11713                         ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
11714                                 ps.readUserState(userId), userId, ps);
11715                         if (ai != null) {
11716                             finalList.add(ai);
11717                         }
11718                     }
11719                 }
11720             }
11721         }
11722 
11723         return finalList;
11724     }
11725 
11726     @Override
resolveContentProvider(String name, int flags, int userId)11727     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
11728         return resolveContentProviderInternal(name, flags, userId);
11729     }
11730 
resolveContentProvider(String name, int flags, int userId, int callingUid)11731     public ProviderInfo resolveContentProvider(String name, int flags, int userId, int callingUid) {
11732         return resolveContentProviderInternal(name, flags, userId, callingUid);
11733     }
11734 
resolveContentProviderInternal(String name, int flags, int userId)11735     private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
11736         return resolveContentProviderInternal(name, flags, userId, Binder.getCallingUid());
11737     }
11738 
resolveContentProviderInternal(String name, int flags, int userId, int callingUid)11739     private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId,
11740             int callingUid) {
11741         if (!mUserManager.exists(userId)) return null;
11742         flags = updateFlagsForComponent(flags, userId);
11743         final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
11744         boolean checkedGrants = false;
11745         if (providerInfo != null) {
11746             // Looking for cross-user grants before enforcing the typical cross-users permissions
11747             if (userId != UserHandle.getUserId(callingUid)) {
11748                 final UriGrantsManagerInternal ugmInternal =
11749                         mInjector.getLocalService(UriGrantsManagerInternal.class);
11750                 checkedGrants =
11751                         ugmInternal.checkAuthorityGrants(callingUid, providerInfo, userId, true);
11752             }
11753         }
11754         if (!checkedGrants) {
11755             enforceCrossUserPermission(callingUid, userId, false, false, "resolveContentProvider");
11756         }
11757         if (providerInfo == null) {
11758             return null;
11759         }
11760         synchronized (mLock) {
11761             if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
11762                 return null;
11763             }
11764             final PackageSetting ps = mSettings.getPackageLPr(providerInfo.packageName);
11765             final ComponentName component =
11766                     new ComponentName(providerInfo.packageName, providerInfo.name);
11767             if (shouldFilterApplicationLocked(ps, callingUid, component, TYPE_PROVIDER, userId)) {
11768                 return null;
11769             }
11770             return providerInfo;
11771         }
11772     }
11773 
11774     /**
11775      * @deprecated
11776      */
11777     @Deprecated
querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)11778     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
11779         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
11780             return;
11781         }
11782         final List<String> names = new ArrayList<>();
11783         final List<ProviderInfo> infos = new ArrayList<>();
11784         final int callingUserId = UserHandle.getCallingUserId();
11785         mComponentResolver.querySyncProviders(
11786                 names, infos, mSafeMode, callingUserId);
11787         synchronized (mLock) {
11788             for (int i = infos.size() - 1; i >= 0; i--) {
11789                 final ProviderInfo providerInfo = infos.get(i);
11790                 final PackageSetting ps = mSettings.getPackageLPr(providerInfo.packageName);
11791                 final ComponentName component =
11792                         new ComponentName(providerInfo.packageName, providerInfo.name);
11793                 if (!shouldFilterApplicationLocked(ps, Binder.getCallingUid(), component,
11794                         TYPE_PROVIDER, callingUserId)) {
11795                     continue;
11796                 }
11797                 infos.remove(i);
11798                 names.remove(i);
11799             }
11800         }
11801         if (!names.isEmpty()) {
11802             outNames.addAll(names);
11803         }
11804         if (!infos.isEmpty()) {
11805             outInfo.addAll(infos);
11806         }
11807     }
11808 
11809     @Override
queryContentProviders(String processName, int uid, int flags, String metaDataKey)11810     public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
11811             int uid, int flags, String metaDataKey) {
11812         final int callingUid = Binder.getCallingUid();
11813         final int userId = processName != null ? UserHandle.getUserId(uid)
11814                 : UserHandle.getCallingUserId();
11815         if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
11816         flags = updateFlagsForComponent(flags, userId);
11817         ArrayList<ProviderInfo> finalList = null;
11818         final List<ProviderInfo> matchList =
11819                 mComponentResolver.queryProviders(processName, metaDataKey, uid, flags, userId);
11820         final int listSize = (matchList == null ? 0 : matchList.size());
11821         synchronized (mLock) {
11822             for (int i = 0; i < listSize; i++) {
11823                 final ProviderInfo providerInfo = matchList.get(i);
11824                 if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
11825                     continue;
11826                 }
11827                 final PackageSetting ps = mSettings.getPackageLPr(providerInfo.packageName);
11828                 final ComponentName component =
11829                         new ComponentName(providerInfo.packageName, providerInfo.name);
11830                 if (shouldFilterApplicationLocked(
11831                         ps, callingUid, component, TYPE_PROVIDER, userId)) {
11832                     continue;
11833                 }
11834                 if (finalList == null) {
11835                     finalList = new ArrayList<>(listSize - i);
11836                 }
11837                 finalList.add(providerInfo);
11838             }
11839         }
11840 
11841         if (finalList != null) {
11842             finalList.sort(sProviderInitOrderSorter);
11843             return new ParceledListSlice<>(finalList);
11844         }
11845 
11846         return ParceledListSlice.emptyList();
11847     }
11848 
11849     @Override
getInstrumentationInfo(ComponentName component, int flags)11850     public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
11851         // reader
11852         synchronized (mLock) {
11853             final int callingUid = Binder.getCallingUid();
11854             final int callingUserId = UserHandle.getUserId(callingUid);
11855             String packageName = component.getPackageName();
11856             final PackageSetting ps = mSettings.getPackageLPr(packageName);
11857             AndroidPackage pkg = mPackages.get(packageName);
11858             if (ps == null || pkg == null) return null;
11859             if (shouldFilterApplicationLocked(
11860                     ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
11861                 return null;
11862             }
11863             final ParsedInstrumentation i = mInstrumentation.get(component);
11864             return PackageInfoUtils.generateInstrumentationInfo(i, pkg, flags, callingUserId, ps);
11865         }
11866     }
11867 
11868     @Override
queryInstrumentation( String targetPackage, int flags)11869     public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
11870             String targetPackage, int flags) {
11871         final int callingUid = Binder.getCallingUid();
11872         final int callingUserId = UserHandle.getUserId(callingUid);
11873         synchronized (mLock) {
11874             final PackageSetting ps = mSettings.getPackageLPr(targetPackage);
11875             if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
11876                 return ParceledListSlice.emptyList();
11877             }
11878         }
11879         return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags,
11880                 callingUserId));
11881     }
11882 
queryInstrumentationInternal(String targetPackage, int flags, int userId)11883     private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
11884             int flags, int userId) {
11885         ArrayList<InstrumentationInfo> finalList = new ArrayList<>();
11886 
11887         // reader
11888         synchronized (mLock) {
11889             final int numInstrumentations = mInstrumentation.size();
11890             for (int index = 0; index < numInstrumentations; index++) {
11891                 final ParsedInstrumentation p = mInstrumentation.valueAt(index);
11892                 if (targetPackage == null
11893                         || targetPackage.equals(p.getTargetPackage())) {
11894                     String packageName = p.getPackageName();
11895                     AndroidPackage pkg = mPackages.get(packageName);
11896                     PackageSetting pkgSetting = getPackageSetting(packageName);
11897                     if (pkg != null) {
11898                         InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
11899                                 pkg, flags, userId, pkgSetting);
11900                         if (ii != null) {
11901                             finalList.add(ii);
11902                         }
11903                     }
11904                 }
11905             }
11906         }
11907 
11908         return finalList;
11909     }
11910 
scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime, PackageParser2 packageParser, ExecutorService executorService)11911     private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags,
11912             long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
11913         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
11914         try {
11915             scanDirLI(scanDir, parseFlags, scanFlags, currentTime, packageParser, executorService);
11916         } finally {
11917             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11918         }
11919     }
11920 
scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime, PackageParser2 packageParser, ExecutorService executorService)11921     private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime,
11922             PackageParser2 packageParser, ExecutorService executorService) {
11923         final File[] files = scanDir.listFiles();
11924         if (ArrayUtils.isEmpty(files)) {
11925             Log.d(TAG, "No files in app dir " + scanDir);
11926             return;
11927         }
11928 
11929         if (DEBUG_PACKAGE_SCANNING) {
11930             Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
11931                     + " flags=0x" + Integer.toHexString(parseFlags));
11932         }
11933 
11934         ParallelPackageParser parallelPackageParser =
11935                 new ParallelPackageParser(packageParser, executorService);
11936 
11937         // Submit files for parsing in parallel
11938         int fileCount = 0;
11939         for (File file : files) {
11940             final boolean isPackage = (isApkFile(file) || file.isDirectory())
11941                     && !PackageInstallerService.isStageName(file.getName());
11942             if (!isPackage) {
11943                 // Ignore entries which are not packages
11944                 continue;
11945             }
11946             parallelPackageParser.submit(file, parseFlags);
11947             fileCount++;
11948         }
11949 
11950         // Process results one by one
11951         for (; fileCount > 0; fileCount--) {
11952             ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
11953             Throwable throwable = parseResult.throwable;
11954             int errorCode = PackageManager.INSTALL_SUCCEEDED;
11955             String errorMsg = null;
11956 
11957             if (throwable == null) {
11958                 // TODO(toddke): move lower in the scan chain
11959                 // Static shared libraries have synthetic package names
11960                 if (parseResult.parsedPackage.isStaticSharedLibrary()) {
11961                     renameStaticSharedLibraryPackage(parseResult.parsedPackage);
11962                 }
11963                 try {
11964                     addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
11965                             currentTime, null);
11966                 } catch (PackageManagerException e) {
11967                     errorCode = e.error;
11968                     errorMsg = "Failed to scan " + parseResult.scanFile + ": " + e.getMessage();
11969                     Slog.w(TAG, errorMsg);
11970                 }
11971             } else if (throwable instanceof PackageParserException) {
11972                 PackageParserException e = (PackageParserException)
11973                         throwable;
11974                 errorCode = e.error;
11975                 errorMsg = "Failed to parse " + parseResult.scanFile + ": " + e.getMessage();
11976                 Slog.w(TAG, errorMsg);
11977             } else {
11978                 throw new IllegalStateException("Unexpected exception occurred while parsing "
11979                         + parseResult.scanFile, throwable);
11980             }
11981 
11982             if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) {
11983                 mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath(), errorMsg);
11984             }
11985 
11986             // Delete invalid userdata apps
11987             if ((scanFlags & SCAN_AS_SYSTEM) == 0
11988                     && errorCode != PackageManager.INSTALL_SUCCEEDED) {
11989                 logCriticalInfo(Log.WARN,
11990                         "Deleting invalid package at " + parseResult.scanFile);
11991                 removeCodePathLI(parseResult.scanFile);
11992             }
11993         }
11994     }
11995 
reportSettingsProblem(int priority, String msg)11996     public static void reportSettingsProblem(int priority, String msg) {
11997         logCriticalInfo(priority, msg);
11998     }
11999 
collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage, boolean forceCollect, boolean skipVerify)12000     private void collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage,
12001             boolean forceCollect, boolean skipVerify) throws PackageManagerException {
12002         // When upgrading from pre-N MR1, verify the package time stamp using the package
12003         // directory and not the APK file.
12004         final long lastModifiedTime = mIsPreNMR1Upgrade
12005                 ? new File(parsedPackage.getPath()).lastModified()
12006                 : getLastModifiedTime(parsedPackage);
12007         final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(parsedPackage);
12008         if (ps != null && !forceCollect
12009                 && ps.getPathString().equals(parsedPackage.getPath())
12010                 && ps.timeStamp == lastModifiedTime
12011                 && !isCompatSignatureUpdateNeeded(settingsVersionForPackage)
12012                 && !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) {
12013             if (ps.signatures.mSigningDetails.signatures != null
12014                     && ps.signatures.mSigningDetails.signatures.length != 0
12015                     && ps.signatures.mSigningDetails.signatureSchemeVersion
12016                             != SignatureSchemeVersion.UNKNOWN) {
12017                 // Optimization: reuse the existing cached signing data
12018                 // if the package appears to be unchanged.
12019                 parsedPackage.setSigningDetails(
12020                         new PackageParser.SigningDetails(ps.signatures.mSigningDetails));
12021                 return;
12022             }
12023 
12024             Slog.w(TAG, "PackageSetting for " + ps.name
12025                     + " is missing signatures.  Collecting certs again to recover them.");
12026         } else {
12027             Slog.i(TAG, parsedPackage.getPath() + " changed; collecting certs"
12028                     + (forceCollect ? " (forced)" : ""));
12029         }
12030 
12031         try {
12032             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
12033             parsedPackage.setSigningDetails(
12034                     ParsingPackageUtils.getSigningDetails(parsedPackage, skipVerify));
12035         } catch (PackageParserException e) {
12036             throw PackageManagerException.from(e);
12037         } finally {
12038             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12039         }
12040     }
12041 
12042     /**
12043      * Clear the package profile if this was an upgrade and the package
12044      * version was updated.
12045      */
maybeClearProfilesForUpgradesLI( @ullable PackageSetting originalPkgSetting, @NonNull AndroidPackage pkg)12046     private void maybeClearProfilesForUpgradesLI(
12047             @Nullable PackageSetting originalPkgSetting,
12048             @NonNull AndroidPackage pkg) {
12049         if (originalPkgSetting == null || !isDeviceUpgrading()) {
12050           return;
12051         }
12052         if (originalPkgSetting.versionCode == pkg.getVersionCode()) {
12053           return;
12054         }
12055 
12056         clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
12057         if (DEBUG_INSTALL) {
12058             Slog.d(TAG, originalPkgSetting.name
12059                   + " clear profile due to version change "
12060                   + originalPkgSetting.versionCode + " != "
12061                   + pkg.getVersionCode());
12062         }
12063     }
12064 
12065     /**
12066      *  Traces a package scan.
12067      *  @see #scanPackageLI(File, int, int, long, UserHandle)
12068      */
12069     @GuardedBy({"mInstallLock", "mLock"})
scanPackageTracedLI(File scanFile, final int parseFlags, int scanFlags, long currentTime, UserHandle user)12070     private AndroidPackage scanPackageTracedLI(File scanFile, final int parseFlags,
12071             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
12072         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
12073         try {
12074             return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
12075         } finally {
12076             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12077         }
12078     }
12079 
12080     /**
12081      *  Scans a package and returns the newly parsed package.
12082      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
12083      */
12084     @GuardedBy({"mInstallLock", "mLock"})
scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user)12085     private AndroidPackage scanPackageLI(File scanFile, int parseFlags, int scanFlags,
12086             long currentTime, UserHandle user) throws PackageManagerException {
12087         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
12088 
12089         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
12090         final ParsedPackage parsedPackage;
12091         try (PackageParser2 pp = mInjector.getScanningPackageParser()) {
12092             parsedPackage = pp.parsePackage(scanFile, parseFlags, false);
12093         } catch (PackageParserException e) {
12094             throw PackageManagerException.from(e);
12095         } finally {
12096             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12097         }
12098 
12099         // Static shared libraries have synthetic package names
12100         if (parsedPackage.isStaticSharedLibrary()) {
12101             renameStaticSharedLibraryPackage(parsedPackage);
12102         }
12103 
12104         return addForInitLI(parsedPackage, parseFlags, scanFlags, currentTime, user);
12105     }
12106 
12107     /**
12108      * Returns if forced apk verification can be skipped for the whole package, including splits.
12109      */
canSkipForcedPackageVerification(AndroidPackage pkg)12110     private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
12111         if (!canSkipForcedApkVerification(pkg.getBaseApkPath())) {
12112             return false;
12113         }
12114         // TODO: Allow base and splits to be verified individually.
12115         String[] splitCodePaths = pkg.getSplitCodePaths();
12116         if (!ArrayUtils.isEmpty(splitCodePaths)) {
12117             for (int i = 0; i < splitCodePaths.length; i++) {
12118                 if (!canSkipForcedApkVerification(splitCodePaths[i])) {
12119                     return false;
12120                 }
12121             }
12122         }
12123         return true;
12124     }
12125 
12126     /**
12127      * Returns if forced apk verification can be skipped, depending on current FSVerity setup and
12128      * whether the apk contains signed root hash.  Note that the signer's certificate still needs to
12129      * match one in a trusted source, and should be done separately.
12130      */
canSkipForcedApkVerification(String apkPath)12131     private boolean canSkipForcedApkVerification(String apkPath) {
12132         if (!PackageManagerServiceUtils.isLegacyApkVerityEnabled()) {
12133             return VerityUtils.hasFsverity(apkPath);
12134         }
12135 
12136         try {
12137             final byte[] rootHashObserved = VerityUtils.generateApkVerityRootHash(apkPath);
12138             if (rootHashObserved == null) {
12139                 return false;  // APK does not contain Merkle tree root hash.
12140             }
12141             synchronized (mInstallLock) {
12142                 // Returns whether the observed root hash matches what kernel has.
12143                 mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
12144                 return true;
12145             }
12146         } catch (InstallerException | IOException | DigestException |
12147                 NoSuchAlgorithmException e) {
12148             Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
12149         }
12150         return false;
12151     }
12152 
12153     /**
12154      * Adds a new package to the internal data structures during platform initialization.
12155      * <p>After adding, the package is known to the system and available for querying.
12156      * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
12157      * etc...], additional checks are performed. Basic verification [such as ensuring
12158      * matching signatures, checking version codes, etc...] occurs if the package is
12159      * identical to a previously known package. If the package fails a signature check,
12160      * the version installed on /data will be removed. If the version of the new package
12161      * is less than or equal than the version on /data, it will be ignored.
12162      * <p>Regardless of the package location, the results are applied to the internal
12163      * structures and the package is made available to the rest of the system.
12164      * <p>NOTE: The return value should be removed. It's the passed in package object.
12165      */
12166     @GuardedBy({"mInstallLock", "mLock"})
addForInitLI(ParsedPackage parsedPackage, @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user)12167     private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
12168             @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
12169             @Nullable UserHandle user)
12170                     throws PackageManagerException {
12171         final boolean scanSystemPartition =
12172                 (parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0;
12173         final String renamedPkgName;
12174         final PackageSetting disabledPkgSetting;
12175         final boolean isSystemPkgUpdated;
12176         final boolean pkgAlreadyExists;
12177         PackageSetting pkgSetting;
12178 
12179         synchronized (mLock) {
12180             renamedPkgName = mSettings.getRenamedPackageLPr(parsedPackage.getRealPackage());
12181             final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
12182             if (realPkgName != null) {
12183                 ensurePackageRenamed(parsedPackage, renamedPkgName);
12184             }
12185             final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
12186                     renamedPkgName);
12187             final PackageSetting installedPkgSetting = mSettings.getPackageLPr(
12188                     parsedPackage.getPackageName());
12189             pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
12190             pkgAlreadyExists = pkgSetting != null;
12191             final String disabledPkgName = pkgAlreadyExists
12192                     ? pkgSetting.name : parsedPackage.getPackageName();
12193             if (scanSystemPartition && !pkgAlreadyExists
12194                     && mSettings.getDisabledSystemPkgLPr(disabledPkgName) != null) {
12195                 // The updated-package data for /system apk remains inconsistently
12196                 // after the package data for /data apk is lost accidentally.
12197                 // To recover it, enable /system apk and install it as non-updated system app.
12198                 Slog.w(TAG, "Inconsistent package setting of updated system app for "
12199                         + disabledPkgName + ". To recover it, enable the system app"
12200                         + "and install it as non-updated system app.");
12201                 mSettings.removeDisabledSystemPackageLPw(disabledPkgName);
12202             }
12203             disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
12204             isSystemPkgUpdated = disabledPkgSetting != null;
12205 
12206             if (DEBUG_INSTALL && isSystemPkgUpdated) {
12207                 Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
12208             }
12209 
12210             final SharedUserSetting sharedUserSetting = (parsedPackage.getSharedUserId() != null)
12211                     ? mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
12212                             0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
12213                     : null;
12214             if (DEBUG_PACKAGE_SCANNING
12215                     && (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0
12216                     && sharedUserSetting != null) {
12217                 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
12218                         + " (uid=" + sharedUserSetting.userId + "):"
12219                         + " packages=" + sharedUserSetting.packages);
12220             }
12221 
12222             if (scanSystemPartition) {
12223                 if (isSystemPkgUpdated) {
12224                     // we're updating the disabled package, so, scan it as the package setting
12225                     boolean isPlatformPackage = mPlatformPackage != null
12226                             && Objects.equals(mPlatformPackage.getPackageName(),
12227                             parsedPackage.getPackageName());
12228                     final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
12229                             null, disabledPkgSetting /* pkgSetting */,
12230                             null /* disabledPkgSetting */, null /* originalPkgSetting */,
12231                             null, parseFlags, scanFlags, isPlatformPackage, user, null);
12232                     applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, true);
12233                     final ScanResult scanResult =
12234                             scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
12235                     if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
12236                         scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
12237                     }
12238                 }
12239             }
12240         }
12241 
12242         final boolean newPkgChangedPaths = pkgAlreadyExists
12243                 && !pkgSetting.getPathString().equals(parsedPackage.getPath());
12244         final boolean newPkgVersionGreater =
12245                 pkgAlreadyExists && parsedPackage.getLongVersionCode() > pkgSetting.versionCode;
12246         final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
12247                 && newPkgChangedPaths && newPkgVersionGreater;
12248         if (isSystemPkgBetter) {
12249             // The version of the application on /system is greater than the version on
12250             // /data. Switch back to the application on /system.
12251             // It's safe to assume the application on /system will correctly scan. If not,
12252             // there won't be a working copy of the application.
12253             synchronized (mLock) {
12254                 // just remove the loaded entries from package lists
12255                 mPackages.remove(pkgSetting.name);
12256             }
12257 
12258             logCriticalInfo(Log.WARN,
12259                     "System package updated;"
12260                     + " name: " + pkgSetting.name
12261                     + "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode()
12262                     + "; " + pkgSetting.getPathString()
12263                             + " --> " + parsedPackage.getPath());
12264 
12265             final InstallArgs args = createInstallArgsForExisting(
12266                     pkgSetting.getPathString(), getAppDexInstructionSets(
12267                             pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
12268             args.cleanUpResourcesLI();
12269             synchronized (mLock) {
12270                 mSettings.enableSystemPackageLPw(pkgSetting.name);
12271             }
12272         }
12273 
12274         // The version of the application on the /system partition is less than or
12275         // equal to the version on the /data partition. Throw an exception and use
12276         // the application already installed on the /data partition.
12277         if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
12278             // In the case of a skipped package, commitReconciledScanResultLocked is not called to
12279             // add the object to the "live" data structures, so this is the final mutation step
12280             // for the package. Which means it needs to be finalized here to cache derived fields.
12281             // This is relevant for cases where the disabled system package is used for flags or
12282             // other metadata.
12283             ((ParsedPackage) parsedPackage).hideAsFinal();
12284             throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName()
12285                     + " at " + parsedPackage.getPath() + " ignored: updated version "
12286                     + pkgSetting.versionCode + " better than this "
12287                     + parsedPackage.getLongVersionCode());
12288         }
12289 
12290         // Verify certificates against what was last scanned. Force re-collecting certificate in two
12291         // special cases:
12292         // 1) when scanning system, force re-collect only if system is upgrading.
12293         // 2) when scannning /data, force re-collect only if the app is privileged (updated from
12294         // preinstall, or treated as privileged, e.g. due to shared user ID).
12295         final boolean forceCollect = scanSystemPartition ? mIsUpgrade
12296                 : PackageManagerServiceUtils.isApkVerificationForced(pkgSetting);
12297         if (DEBUG_VERIFY && forceCollect) {
12298             Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName());
12299         }
12300 
12301         // Full APK verification can be skipped during certificate collection, only if the file is
12302         // in verified partition, or can be verified on access (when apk verity is enabled). In both
12303         // cases, only data in Signing Block is verified instead of the whole file.
12304         // TODO(b/136132412): skip for Incremental installation
12305         final boolean skipVerify = scanSystemPartition
12306                 || (forceCollect && canSkipForcedPackageVerification(parsedPackage));
12307         collectCertificatesLI(pkgSetting, parsedPackage, forceCollect, skipVerify);
12308 
12309         // Reset profile if the application version is changed
12310         maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage);
12311 
12312         /*
12313          * A new system app appeared, but we already had a non-system one of the
12314          * same name installed earlier.
12315          */
12316         boolean shouldHideSystemApp = false;
12317         // A new application appeared on /system, but, we already have a copy of
12318         // the application installed on /data.
12319         if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
12320                 && !pkgSetting.isSystem()) {
12321 
12322             if (!parsedPackage.getSigningDetails()
12323                     .checkCapability(pkgSetting.signatures.mSigningDetails,
12324                     PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
12325                             && !pkgSetting.signatures.mSigningDetails.checkCapability(
12326                                     parsedPackage.getSigningDetails(),
12327                                     PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
12328                 logCriticalInfo(Log.WARN,
12329                         "System package signature mismatch;"
12330                         + " name: " + pkgSetting.name);
12331                 try (@SuppressWarnings("unused") PackageFreezer freezer = freezePackage(
12332                         parsedPackage.getPackageName(),
12333                         "scanPackageInternalLI")) {
12334                     deletePackageLIF(parsedPackage.getPackageName(), null, true,
12335                             mUserManager.getUserIds(), 0, null, false, null);
12336                 }
12337                 pkgSetting = null;
12338             } else if (newPkgVersionGreater) {
12339                 // The application on /system is newer than the application on /data.
12340                 // Simply remove the application on /data [keeping application data]
12341                 // and replace it with the version on /system.
12342                 logCriticalInfo(Log.WARN,
12343                         "System package enabled;"
12344                                 + " name: " + pkgSetting.name
12345                                 + "; " + pkgSetting.versionCode + " --> "
12346                                 + parsedPackage.getLongVersionCode()
12347                                 + "; " + pkgSetting.getPathString() + " --> "
12348                                 + parsedPackage.getPath());
12349                 InstallArgs args = createInstallArgsForExisting(
12350                         pkgSetting.getPathString(), getAppDexInstructionSets(
12351                                 pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
12352                 synchronized (mInstallLock) {
12353                     args.cleanUpResourcesLI();
12354                 }
12355             } else {
12356                 // The application on /system is older than the application on /data. Hide
12357                 // the application on /system and the version on /data will be scanned later
12358                 // and re-added like an update.
12359                 shouldHideSystemApp = true;
12360                 logCriticalInfo(Log.INFO,
12361                         "System package disabled;"
12362                                 + " name: " + pkgSetting.name
12363                                 + "; old: " + pkgSetting.getPathString() + " @ "
12364                                 + pkgSetting.versionCode
12365                                 + "; new: " + parsedPackage.getPath() + " @ "
12366                                 + parsedPackage.getPath());
12367             }
12368         }
12369 
12370         final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, scanFlags
12371                 | SCAN_UPDATE_SIGNATURE, currentTime, user, null);
12372         if (scanResult.success) {
12373             synchronized (mLock) {
12374                 boolean appIdCreated = false;
12375                 try {
12376                     final String pkgName = scanResult.pkgSetting.name;
12377                     final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(
12378                             new ReconcileRequest(
12379                                     Collections.singletonMap(pkgName, scanResult),
12380                                     mSharedLibraries,
12381                                     mPackages,
12382                                     Collections.singletonMap(
12383                                             pkgName, getSettingsVersionForPackage(parsedPackage)),
12384                                     Collections.singletonMap(pkgName,
12385                                             getSharedLibLatestVersionSetting(scanResult))),
12386                             mSettings.getKeySetManagerService(), mInjector);
12387                     appIdCreated = optimisticallyRegisterAppId(scanResult);
12388                     commitReconciledScanResultLocked(
12389                             reconcileResult.get(pkgName), mUserManager.getUserIds());
12390                 } catch (PackageManagerException e) {
12391                     if (appIdCreated) {
12392                         cleanUpAppIdCreation(scanResult);
12393                     }
12394                     throw e;
12395                 }
12396             }
12397         }
12398 
12399         if (shouldHideSystemApp) {
12400             synchronized (mLock) {
12401                 mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true);
12402             }
12403         }
12404         if (mIncrementalManager != null && isIncrementalPath(parsedPackage.getPath())) {
12405             if (pkgSetting != null && pkgSetting.isPackageLoading()) {
12406                 // Continue monitoring loading progress of active incremental packages
12407                 final IncrementalStatesCallback incrementalStatesCallback =
12408                         new IncrementalStatesCallback(parsedPackage.getPackageName(),
12409                                 UserHandle.getUid(UserHandle.USER_ALL, pkgSetting.appId),
12410                                 getInstalledUsers(pkgSetting, UserHandle.USER_ALL));
12411                 pkgSetting.setIncrementalStatesCallback(incrementalStatesCallback);
12412                 mIncrementalManager.registerLoadingProgressCallback(parsedPackage.getPath(),
12413                         new IncrementalProgressListener(parsedPackage.getPackageName()));
12414             }
12415         }
12416         return scanResult.pkgSetting.pkg;
12417     }
12418 
12419     // TODO:(b/135203078): Move to parsing
renameStaticSharedLibraryPackage(ParsedPackage parsedPackage)12420     private static void renameStaticSharedLibraryPackage(ParsedPackage parsedPackage) {
12421         // Derive the new package synthetic package name
12422         parsedPackage.setPackageName(toStaticSharedLibraryPackageName(
12423                 parsedPackage.getPackageName(), parsedPackage.getStaticSharedLibVersion()));
12424     }
12425 
toStaticSharedLibraryPackageName( String packageName, long libraryVersion)12426     private static String toStaticSharedLibraryPackageName(
12427             String packageName, long libraryVersion) {
12428         return packageName + STATIC_SHARED_LIB_DELIMITER + libraryVersion;
12429     }
12430 
fixProcessName(String defProcessName, String processName)12431     static String fixProcessName(String defProcessName, String processName) {
12432         if (processName == null) {
12433             return defProcessName;
12434         }
12435         return processName;
12436     }
12437 
12438     /**
12439      * Enforces that only the system UID or root's UID can call a method exposed
12440      * via Binder.
12441      *
12442      * @param message used as message if SecurityException is thrown
12443      * @throws SecurityException if the caller is not system or root
12444      */
enforceSystemOrRoot(String message)12445     private static void enforceSystemOrRoot(String message) {
12446         final int uid = Binder.getCallingUid();
12447         if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
12448             throw new SecurityException(message);
12449         }
12450     }
12451 
12452     /**
12453      * Enforces that only the system UID or root's UID or shell's UID can call
12454      * a method exposed via Binder.
12455      *
12456      * @param message used as message if SecurityException is thrown
12457      * @throws SecurityException if the caller is not system or shell
12458      */
enforceSystemOrRootOrShell(String message)12459     private static void enforceSystemOrRootOrShell(String message) {
12460         final int uid = Binder.getCallingUid();
12461         if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID && uid != Process.SHELL_UID) {
12462             throw new SecurityException(message);
12463         }
12464     }
12465 
12466     /**
12467      * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
12468      * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
12469      *
12470      * @param checkShell whether to prevent shell from access if there's a debugging restriction
12471      * @param message the message to log on security exception
12472      */
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)12473     void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
12474             boolean requireFullPermission, boolean checkShell, String message) {
12475         mComputer.enforceCrossUserPermission(callingUid, userId,
12476                 requireFullPermission, checkShell, message);
12477     }
12478 
12479     /**
12480      * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
12481      * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
12482      *
12483      * @param checkShell whether to prevent shell from access if there's a debugging restriction
12484      * @param requirePermissionWhenSameUser When {@code true}, still require the cross user
12485      *                                      permission to be held even if the callingUid and userId
12486      *                                      reference the same user.
12487      * @param message the message to log on security exception
12488      */
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)12489     private void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
12490             boolean requireFullPermission, boolean checkShell,
12491             boolean requirePermissionWhenSameUser, String message) {
12492         mComputer.enforceCrossUserPermission(callingUid, userId,
12493                 requireFullPermission, checkShell,
12494                 requirePermissionWhenSameUser, message);
12495     }
12496 
12497     /**
12498      * Checks if the request is from the system or an app that has the appropriate cross-user
12499      * permissions defined as follows:
12500      * <ul>
12501      * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
12502      * <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group
12503      * to the caller.</li>
12504      * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile
12505      * group as the caller.</li>
12506      * </ul>
12507      *
12508      * @param checkShell whether to prevent shell from access if there's a debugging restriction
12509      * @param message the message to log on security exception
12510      */
enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)12511     private void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
12512             boolean requireFullPermission, boolean checkShell, String message) {
12513         mComputer.enforceCrossUserOrProfilePermission(callingUid, userId,
12514                 requireFullPermission, checkShell, message);
12515     }
12516 
isSameProfileGroup(@serIdInt int callerUserId, @UserIdInt int userId)12517     private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
12518         return mComputer.isSameProfileGroup(callerUserId, userId);
12519     }
12520 
buildInvalidCrossUserPermissionMessage(int callingUid, @UserIdInt int userId, String message, boolean requireFullPermission)12521     private static String buildInvalidCrossUserPermissionMessage(int callingUid,
12522             @UserIdInt int userId, String message, boolean requireFullPermission) {
12523         StringBuilder builder = new StringBuilder();
12524         if (message != null) {
12525             builder.append(message);
12526             builder.append(": ");
12527         }
12528         builder.append("UID ");
12529         builder.append(callingUid);
12530         builder.append(" requires ");
12531         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12532         if (!requireFullPermission) {
12533             builder.append(" or ");
12534             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12535         }
12536         builder.append(" to access user ");
12537         builder.append(userId);
12538         builder.append(".");
12539         return builder.toString();
12540     }
12541 
buildInvalidCrossUserOrProfilePermissionMessage(int callingUid, @UserIdInt int userId, String message, boolean requireFullPermission, boolean isSameProfileGroup)12542     private static String buildInvalidCrossUserOrProfilePermissionMessage(int callingUid,
12543             @UserIdInt int userId, String message, boolean requireFullPermission,
12544             boolean isSameProfileGroup) {
12545         StringBuilder builder = new StringBuilder();
12546         if (message != null) {
12547             builder.append(message);
12548             builder.append(": ");
12549         }
12550         builder.append("UID ");
12551         builder.append(callingUid);
12552         builder.append(" requires ");
12553         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12554         if (!requireFullPermission) {
12555             builder.append(" or ");
12556             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12557             if (isSameProfileGroup) {
12558                 builder.append(" or ");
12559                 builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES);
12560             }
12561         }
12562         builder.append(" to access user ");
12563         builder.append(".");
12564         return builder.toString();
12565     }
12566 
12567     @Override
performFstrimIfNeeded()12568     public void performFstrimIfNeeded() {
12569         enforceSystemOrRoot("Only the system can request fstrim");
12570 
12571         // Before everything else, see whether we need to fstrim.
12572         try {
12573             IStorageManager sm = PackageHelper.getStorageManager();
12574             if (sm != null) {
12575                 boolean doTrim = false;
12576                 final long interval = android.provider.Settings.Global.getLong(
12577                         mContext.getContentResolver(),
12578                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
12579                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
12580                 if (interval > 0) {
12581                     final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
12582                     if (timeSinceLast > interval) {
12583                         doTrim = true;
12584                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
12585                                 + "; running immediately");
12586                     }
12587                 }
12588                 if (doTrim) {
12589                     final boolean dexOptDialogShown;
12590                     synchronized (mLock) {
12591                         dexOptDialogShown = mDexOptDialogShown;
12592                     }
12593                     if (!isFirstBoot() && dexOptDialogShown) {
12594                         try {
12595                             ActivityManager.getService().showBootMessage(
12596                                     mContext.getResources().getString(
12597                                             R.string.android_upgrading_fstrim), true);
12598                         } catch (RemoteException e) {
12599                         }
12600                     }
12601                     sm.runMaintenance();
12602                 }
12603             } else {
12604                 Slog.e(TAG, "storageManager service unavailable!");
12605             }
12606         } catch (RemoteException e) {
12607             // Can't happen; StorageManagerService is local
12608         }
12609     }
12610 
12611     @Override
updatePackagesIfNeeded()12612     public void updatePackagesIfNeeded() {
12613         enforceSystemOrRoot("Only the system can request package update");
12614 
12615         // We need to re-extract after an OTA.
12616         boolean causeUpgrade = isDeviceUpgrading();
12617 
12618         // First boot or factory reset.
12619         // Note: we also handle devices that are upgrading to N right now as if it is their
12620         //       first boot, as they do not have profile data.
12621         boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
12622 
12623         if (!causeUpgrade && !causeFirstBoot) {
12624             return;
12625         }
12626 
12627         List<PackageSetting> pkgSettings;
12628         synchronized (mLock) {
12629             pkgSettings = PackageManagerServiceUtils.getPackagesForDexopt(
12630                     mSettings.getPackagesLocked().values(), this);
12631         }
12632 
12633         List<AndroidPackage> pkgs = new ArrayList<>(pkgSettings.size());
12634         for (int index = 0; index < pkgSettings.size(); index++) {
12635             pkgs.add(pkgSettings.get(index).pkg);
12636         }
12637 
12638         final long startTime = System.nanoTime();
12639         final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
12640                     causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT_AFTER_OTA,
12641                     false /* bootComplete */);
12642 
12643         final int elapsedTimeSeconds =
12644                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
12645 
12646         MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
12647         MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
12648         MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
12649         MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
12650         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
12651     }
12652 
12653     /*
12654      * Return the prebuilt profile path given a package base code path.
12655      */
getPrebuildProfilePath(AndroidPackage pkg)12656     private static String getPrebuildProfilePath(AndroidPackage pkg) {
12657         return pkg.getBaseApkPath() + ".prof";
12658     }
12659 
12660     /**
12661      * Performs dexopt on the set of packages in {@code packages} and returns an int array
12662      * containing statistics about the invocation. The array consists of three elements,
12663      * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
12664      * and {@code numberOfPackagesFailed}.
12665      */
performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog, final int compilationReason, boolean bootComplete)12666     private int[] performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog,
12667             final int compilationReason, boolean bootComplete) {
12668 
12669         int numberOfPackagesVisited = 0;
12670         int numberOfPackagesOptimized = 0;
12671         int numberOfPackagesSkipped = 0;
12672         int numberOfPackagesFailed = 0;
12673         final int numberOfPackagesToDexopt = pkgs.size();
12674 
12675         for (AndroidPackage pkg : pkgs) {
12676             numberOfPackagesVisited++;
12677 
12678             boolean useProfileForDexopt = false;
12679 
12680             if ((isFirstBoot() || isDeviceUpgrading()) && pkg.isSystem()) {
12681                 // Copy over initial preopt profiles since we won't get any JIT samples for methods
12682                 // that are already compiled.
12683                 File profileFile = new File(getPrebuildProfilePath(pkg));
12684                 // Copy profile if it exists.
12685                 if (profileFile.exists()) {
12686                     try {
12687                         // We could also do this lazily before calling dexopt in
12688                         // PackageDexOptimizer to prevent this happening on first boot. The issue
12689                         // is that we don't have a good way to say "do this only once".
12690                         if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
12691                                 pkg.getUid(), pkg.getPackageName(),
12692                                 ArtManager.getProfileName(null))) {
12693                             Log.e(TAG, "Installer failed to copy system profile!");
12694                         } else {
12695                             // Disabled as this causes speed-profile compilation during first boot
12696                             // even if things are already compiled.
12697                             // useProfileForDexopt = true;
12698                         }
12699                     } catch (Exception e) {
12700                         Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
12701                                 e);
12702                     }
12703                 } else {
12704                     PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(
12705                             pkg.getPackageName());
12706                     // Handle compressed APKs in this path. Only do this for stubs with profiles to
12707                     // minimize the number off apps being speed-profile compiled during first boot.
12708                     // The other paths will not change the filter.
12709                     if (disabledPs != null && disabledPs.pkg.isStub()) {
12710                         // The package is the stub one, remove the stub suffix to get the normal
12711                         // package and APK names.
12712                         String systemProfilePath =
12713                                 getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
12714                         profileFile = new File(systemProfilePath);
12715                         // If we have a profile for a compressed APK, copy it to the reference
12716                         // location.
12717                         // Note that copying the profile here will cause it to override the
12718                         // reference profile every OTA even though the existing reference profile
12719                         // may have more data. We can't copy during decompression since the
12720                         // directories are not set up at that point.
12721                         if (profileFile.exists()) {
12722                             try {
12723                                 // We could also do this lazily before calling dexopt in
12724                                 // PackageDexOptimizer to prevent this happening on first boot. The
12725                                 // issue is that we don't have a good way to say "do this only
12726                                 // once".
12727                                 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
12728                                         pkg.getUid(), pkg.getPackageName(),
12729                                         ArtManager.getProfileName(null))) {
12730                                     Log.e(TAG, "Failed to copy system profile for stub package!");
12731                                 } else {
12732                                     useProfileForDexopt = true;
12733                                 }
12734                             } catch (Exception e) {
12735                                 Log.e(TAG, "Failed to copy profile " +
12736                                         profileFile.getAbsolutePath() + " ", e);
12737                             }
12738                         }
12739                     }
12740                 }
12741             }
12742 
12743             if (!mPackageDexOptimizer.canOptimizePackage(pkg)) {
12744                 if (DEBUG_DEXOPT) {
12745                     Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName());
12746                 }
12747                 numberOfPackagesSkipped++;
12748                 continue;
12749             }
12750 
12751             if (DEBUG_DEXOPT) {
12752                 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
12753                         numberOfPackagesToDexopt + ": " + pkg.getPackageName());
12754             }
12755 
12756             if (showDialog) {
12757                 try {
12758                     ActivityManager.getService().showBootMessage(
12759                             mContext.getResources().getString(R.string.android_upgrading_apk,
12760                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
12761                 } catch (RemoteException e) {
12762                 }
12763                 synchronized (mLock) {
12764                     mDexOptDialogShown = true;
12765                 }
12766             }
12767 
12768             int pkgCompilationReason = compilationReason;
12769             if (useProfileForDexopt) {
12770                 // Use background dexopt mode to try and use the profile. Note that this does not
12771                 // guarantee usage of the profile.
12772                 pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
12773             }
12774 
12775             if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
12776                 mArtManagerService.compileLayouts(pkg);
12777             }
12778 
12779             // checkProfiles is false to avoid merging profiles during boot which
12780             // might interfere with background compilation (b/28612421).
12781             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
12782             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
12783             // trade-off worth doing to save boot time work.
12784             int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
12785             if (compilationReason == REASON_FIRST_BOOT) {
12786                 // TODO: This doesn't cover the upgrade case, we should check for this too.
12787                 dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
12788             }
12789             int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
12790                     pkg.getPackageName(),
12791                     pkgCompilationReason,
12792                     dexoptFlags));
12793 
12794             switch (primaryDexOptStaus) {
12795                 case PackageDexOptimizer.DEX_OPT_PERFORMED:
12796                     numberOfPackagesOptimized++;
12797                     break;
12798                 case PackageDexOptimizer.DEX_OPT_SKIPPED:
12799                     numberOfPackagesSkipped++;
12800                     break;
12801                 case PackageDexOptimizer.DEX_OPT_FAILED:
12802                     numberOfPackagesFailed++;
12803                     break;
12804                 default:
12805                     Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
12806                     break;
12807             }
12808         }
12809 
12810         return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
12811                 numberOfPackagesFailed };
12812     }
12813 
12814     @Override
notifyPackageUse(String packageName, int reason)12815     public void notifyPackageUse(String packageName, int reason) {
12816         synchronized (mLock) {
12817             final int callingUid = Binder.getCallingUid();
12818             final int callingUserId = UserHandle.getUserId(callingUid);
12819             if (getInstantAppPackageName(callingUid) != null) {
12820                 if (!isCallerSameApp(packageName, callingUid)) {
12821                     return;
12822                 }
12823             } else {
12824                 if (isInstantAppInternal(packageName, callingUserId, Process.SYSTEM_UID)) {
12825                     return;
12826                 }
12827             }
12828             notifyPackageUseLocked(packageName, reason);
12829         }
12830     }
12831 
12832     @GuardedBy("mLock")
notifyPackageUseLocked(String packageName, int reason)12833     private void notifyPackageUseLocked(String packageName, int reason) {
12834         final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
12835         if (pkgSetting == null) {
12836             return;
12837         }
12838         pkgSetting.getPkgState().setLastPackageUsageTimeInMills(reason, System.currentTimeMillis());
12839     }
12840 
12841     @Override
notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap, String loaderIsa)12842     public void notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap,
12843             String loaderIsa) {
12844         int callingUid = Binder.getCallingUid();
12845         if (PLATFORM_PACKAGE_NAME.equals(loadingPackageName) && callingUid != Process.SYSTEM_UID) {
12846             Slog.w(TAG, "Non System Server process reporting dex loads as system server. uid="
12847                     + callingUid);
12848             // Do not record dex loads from processes pretending to be system server.
12849             // Only the system server should be assigned the package "android", so reject calls
12850             // that don't satisfy the constraint.
12851             //
12852             // notifyDexLoad is a PM API callable from the app process. So in theory, apps could
12853             // craft calls to this API and pretend to be system server. Doing so poses no particular
12854             // danger for dex load reporting or later dexopt, however it is a sensible check to do
12855             // in order to verify the expectations.
12856             return;
12857         }
12858 
12859         int userId = UserHandle.getCallingUserId();
12860         ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
12861         if (ai == null) {
12862             Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
12863                 + loadingPackageName + ", user=" + userId);
12864             return;
12865         }
12866         mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId,
12867                 Process.isIsolated(callingUid));
12868     }
12869 
12870     @Override
registerDexModule(String packageName, String dexModulePath, boolean isSharedModule, IDexModuleRegisterCallback callback)12871     public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
12872             IDexModuleRegisterCallback callback) {
12873         int userId = UserHandle.getCallingUserId();
12874         ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
12875         DexManager.RegisterDexModuleResult result;
12876         if (ai == null) {
12877             Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
12878                      " calling user. package=" + packageName + ", user=" + userId);
12879             result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
12880         } else {
12881             result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
12882         }
12883 
12884         if (callback != null) {
12885             mHandler.post(() -> {
12886                 try {
12887                     callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
12888                 } catch (RemoteException e) {
12889                     Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
12890                 }
12891             });
12892         }
12893     }
12894 
12895     /**
12896      * Ask the package manager to perform a dex-opt with the given compiler filter.
12897      *
12898      * Note: exposed only for the shell command to allow moving packages explicitly to a
12899      *       definite state.
12900      */
12901     @Override
performDexOptMode(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force, boolean bootComplete, String splitName)12902     public boolean performDexOptMode(String packageName,
12903             boolean checkProfiles, String targetCompilerFilter, boolean force,
12904             boolean bootComplete, String splitName) {
12905         enforceSystemOrRootOrShell("performDexOptMode");
12906 
12907         int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
12908                 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
12909                 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
12910         return performDexOpt(new DexoptOptions(packageName, REASON_CMDLINE,
12911                 targetCompilerFilter, splitName, flags));
12912     }
12913 
12914     /**
12915      * Ask the package manager to perform a dex-opt with the given compiler filter on the
12916      * secondary dex files belonging to the given package.
12917      *
12918      * Note: exposed only for the shell command to allow moving packages explicitly to a
12919      *       definite state.
12920      */
12921     @Override
performDexOptSecondary(String packageName, String compilerFilter, boolean force)12922     public boolean performDexOptSecondary(String packageName, String compilerFilter,
12923             boolean force) {
12924         int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
12925                 DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
12926                 DexoptOptions.DEXOPT_BOOT_COMPLETE |
12927                 (force ? DexoptOptions.DEXOPT_FORCE : 0);
12928         return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
12929     }
12930 
performDexOpt(DexoptOptions options)12931     /*package*/ boolean performDexOpt(DexoptOptions options) {
12932         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
12933             return false;
12934         } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
12935             return false;
12936         }
12937 
12938         if (options.isDexoptOnlySecondaryDex()) {
12939             return mDexManager.dexoptSecondaryDex(options);
12940         } else {
12941             int dexoptStatus = performDexOptWithStatus(options);
12942             return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
12943         }
12944     }
12945 
12946     /**
12947      * Perform dexopt on the given package and return one of following result:
12948      *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
12949      *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
12950      *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
12951      */
performDexOptWithStatus(DexoptOptions options)12952     /* package */ int performDexOptWithStatus(DexoptOptions options) {
12953         return performDexOptTraced(options);
12954     }
12955 
performDexOptTraced(DexoptOptions options)12956     private int performDexOptTraced(DexoptOptions options) {
12957         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
12958         try {
12959             return performDexOptInternal(options);
12960         } finally {
12961             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12962         }
12963     }
12964 
12965     // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
12966     // if the package can now be considered up to date for the given filter.
performDexOptInternal(DexoptOptions options)12967     private int performDexOptInternal(DexoptOptions options) {
12968         AndroidPackage p;
12969         PackageSetting pkgSetting;
12970         synchronized (mLock) {
12971             p = mPackages.get(options.getPackageName());
12972             pkgSetting = mSettings.getPackageLPr(options.getPackageName());
12973             if (p == null || pkgSetting == null) {
12974                 // Package could not be found. Report failure.
12975                 return PackageDexOptimizer.DEX_OPT_FAILED;
12976             }
12977             mPackageUsage.maybeWriteAsync(mSettings.getPackagesLocked());
12978             mCompilerStats.maybeWriteAsync();
12979         }
12980         final long callingId = Binder.clearCallingIdentity();
12981         try {
12982             synchronized (mInstallLock) {
12983                 return performDexOptInternalWithDependenciesLI(p, pkgSetting, options);
12984             }
12985         } finally {
12986             Binder.restoreCallingIdentity(callingId);
12987         }
12988     }
12989 
getOptimizablePackages()12990     public ArraySet<String> getOptimizablePackages() {
12991         ArraySet<String> pkgs = new ArraySet<>();
12992         synchronized (mLock) {
12993             for (AndroidPackage p : mPackages.values()) {
12994                 if (mPackageDexOptimizer.canOptimizePackage(p)) {
12995                     pkgs.add(p.getPackageName());
12996                 }
12997             }
12998         }
12999         return pkgs;
13000     }
13001 
performDexOptInternalWithDependenciesLI(AndroidPackage p, @NonNull PackageSetting pkgSetting, DexoptOptions options)13002     private int performDexOptInternalWithDependenciesLI(AndroidPackage p,
13003             @NonNull PackageSetting pkgSetting, DexoptOptions options) {
13004         // System server gets a special path.
13005         if (PLATFORM_PACKAGE_NAME.equals(p.getPackageName())) {
13006             return mDexManager.dexoptSystemServer(options);
13007         }
13008 
13009         // Select the dex optimizer based on the force parameter.
13010         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
13011         //       allocate an object here.
13012         PackageDexOptimizer pdo = options.isForce()
13013                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
13014                 : mPackageDexOptimizer;
13015 
13016         // Dexopt all dependencies first. Note: we ignore the return value and march on
13017         // on errors.
13018         // Note that we are going to call performDexOpt on those libraries as many times as
13019         // they are referenced in packages. When we do a batch of performDexOpt (for example
13020         // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
13021         // and the first package that uses the library will dexopt it. The
13022         // others will see that the compiled code for the library is up to date.
13023         Collection<SharedLibraryInfo> deps = findSharedLibraries(pkgSetting);
13024         final String[] instructionSets = getAppDexInstructionSets(
13025                 AndroidPackageUtils.getPrimaryCpuAbi(p, pkgSetting),
13026                 AndroidPackageUtils.getSecondaryCpuAbi(p, pkgSetting));
13027         if (!deps.isEmpty()) {
13028             DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
13029                     options.getCompilationReason(), options.getCompilerFilter(),
13030                     options.getSplitName(),
13031                     options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
13032             for (SharedLibraryInfo info : deps) {
13033                 AndroidPackage depPackage = null;
13034                 PackageSetting depPackageSetting = null;
13035                 synchronized (mLock) {
13036                     depPackage = mPackages.get(info.getPackageName());
13037                     depPackageSetting = mSettings.getPackageLPr(info.getPackageName());
13038                 }
13039                 if (depPackage != null && depPackageSetting != null) {
13040                     // TODO: Analyze and investigate if we (should) profile libraries.
13041                     pdo.performDexOpt(depPackage, depPackageSetting, instructionSets,
13042                             getOrCreateCompilerPackageStats(depPackage),
13043                             mDexManager.getPackageUseInfoOrDefault(depPackage.getPackageName()),
13044                             libraryOptions);
13045                 } else {
13046                     // TODO(ngeoffray): Support dexopting system shared libraries.
13047                 }
13048             }
13049         }
13050 
13051         return pdo.performDexOpt(p, pkgSetting, instructionSets,
13052                 getOrCreateCompilerPackageStats(p),
13053                 mDexManager.getPackageUseInfoOrDefault(p.getPackageName()), options);
13054     }
13055 
13056     /**
13057      * Reconcile the information we have about the secondary dex files belonging to
13058      * {@code packageName} and the actual dex files. For all dex files that were
13059      * deleted, update the internal records and delete the generated oat files.
13060      */
13061     @Override
reconcileSecondaryDexFiles(String packageName)13062     public void reconcileSecondaryDexFiles(String packageName) {
13063         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13064             return;
13065         } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
13066             return;
13067         }
13068         mDexManager.reconcileSecondaryDexFiles(packageName);
13069     }
13070 
13071     // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
13072     // a reference there.
getDexManager()13073     /*package*/ DexManager getDexManager() {
13074         return mDexManager;
13075     }
13076 
13077     /**
13078      * Execute the background dexopt job immediately.
13079      */
13080     @Override
runBackgroundDexoptJob(@ullable List<String> packageNames)13081     public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
13082         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13083             return false;
13084         }
13085         enforceSystemOrRootOrShell("runBackgroundDexoptJob");
13086         final long identity = Binder.clearCallingIdentity();
13087         try {
13088             return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
13089         } finally {
13090             Binder.restoreCallingIdentity(identity);
13091         }
13092     }
13093 
findSharedLibraries(PackageSetting pkgSetting)13094     private static List<SharedLibraryInfo> findSharedLibraries(PackageSetting pkgSetting) {
13095         if (!pkgSetting.getPkgState().getUsesLibraryInfos().isEmpty()) {
13096             ArrayList<SharedLibraryInfo> retValue = new ArrayList<>();
13097             Set<String> collectedNames = new HashSet<>();
13098             for (SharedLibraryInfo info : pkgSetting.getPkgState().getUsesLibraryInfos()) {
13099                 findSharedLibrariesRecursive(info, retValue, collectedNames);
13100             }
13101             return retValue;
13102         } else {
13103             return Collections.emptyList();
13104         }
13105     }
13106 
findSharedLibrariesRecursive(SharedLibraryInfo info, ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames)13107     private static void findSharedLibrariesRecursive(SharedLibraryInfo info,
13108             ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames) {
13109         if (!collectedNames.contains(info.getName())) {
13110             collectedNames.add(info.getName());
13111             collected.add(info);
13112 
13113             if (info.getDependencies() != null) {
13114                 for (SharedLibraryInfo dep : info.getDependencies()) {
13115                     findSharedLibrariesRecursive(dep, collected, collectedNames);
13116                 }
13117             }
13118         }
13119     }
13120 
findSharedNonSystemLibraries(PackageSetting pkgSetting)13121     List<PackageSetting> findSharedNonSystemLibraries(PackageSetting pkgSetting) {
13122         List<SharedLibraryInfo> deps = findSharedLibraries(pkgSetting);
13123         if (!deps.isEmpty()) {
13124             List<PackageSetting> retValue = new ArrayList<>();
13125             synchronized (mLock) {
13126                 for (SharedLibraryInfo info : deps) {
13127                     PackageSetting depPackageSetting =
13128                             mSettings.getPackageLPr(info.getPackageName());
13129                     if (depPackageSetting != null && depPackageSetting.pkg != null) {
13130                         retValue.add(depPackageSetting);
13131                     }
13132                 }
13133             }
13134             return retValue;
13135         } else {
13136             return Collections.emptyList();
13137         }
13138     }
13139 
13140     @Nullable
getSharedLibraryInfoLPr(String name, long version)13141     private SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
13142         return mComputer.getSharedLibraryInfoLPr(name, version);
13143     }
13144 
13145     @Nullable
getSharedLibraryInfo(String name, long version, Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries)13146     private static SharedLibraryInfo getSharedLibraryInfo(String name, long version,
13147             Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries,
13148             @Nullable Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries) {
13149         if (newLibraries != null) {
13150             final WatchedLongSparseArray<SharedLibraryInfo> versionedLib = newLibraries.get(name);
13151             SharedLibraryInfo info = null;
13152             if (versionedLib != null) {
13153                 info = versionedLib.get(version);
13154             }
13155             if (info != null) {
13156                 return info;
13157             }
13158         }
13159         final WatchedLongSparseArray<SharedLibraryInfo> versionedLib = existingLibraries.get(name);
13160         if (versionedLib == null) {
13161             return null;
13162         }
13163         return versionedLib.get(version);
13164     }
13165 
getLatestSharedLibraVersionLPr(AndroidPackage pkg)13166     private SharedLibraryInfo getLatestSharedLibraVersionLPr(AndroidPackage pkg) {
13167         WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
13168                 pkg.getStaticSharedLibName());
13169         if (versionedLib == null) {
13170             return null;
13171         }
13172         long previousLibVersion = -1;
13173         final int versionCount = versionedLib.size();
13174         for (int i = 0; i < versionCount; i++) {
13175             final long libVersion = versionedLib.keyAt(i);
13176             if (libVersion < pkg.getStaticSharedLibVersion()) {
13177                 previousLibVersion = Math.max(previousLibVersion, libVersion);
13178             }
13179         }
13180         if (previousLibVersion >= 0) {
13181             return versionedLib.get(previousLibVersion);
13182         }
13183         return null;
13184     }
13185 
13186 
13187     @Nullable
getSharedLibLatestVersionSetting(@onNull ScanResult scanResult)13188     private PackageSetting getSharedLibLatestVersionSetting(@NonNull ScanResult scanResult) {
13189         PackageSetting sharedLibPackage = null;
13190         synchronized (mLock) {
13191             final SharedLibraryInfo latestSharedLibraVersionLPr =
13192                     getLatestSharedLibraVersionLPr(scanResult.request.parsedPackage);
13193             if (latestSharedLibraVersionLPr != null) {
13194                 sharedLibPackage = mSettings.getPackageLPr(
13195                         latestSharedLibraVersionLPr.getPackageName());
13196             }
13197         }
13198         return sharedLibPackage;
13199     }
13200 
shutdown()13201     public void shutdown() {
13202         mCompilerStats.writeNow();
13203         mDexManager.writePackageDexUsageNow();
13204         PackageWatchdog.getInstance(mContext).writeNow();
13205 
13206         synchronized (mLock) {
13207             mPackageUsage.writeNow(mSettings.getPackagesLocked());
13208 
13209             // This is the last chance to write out pending restriction settings
13210             if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
13211                 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
13212                 for (int userId : mDirtyUsers) {
13213                     mSettings.writePackageRestrictionsLPr(userId);
13214                 }
13215                 mDirtyUsers.clear();
13216             }
13217         }
13218     }
13219 
13220     @Override
dumpProfiles(String packageName)13221     public void dumpProfiles(String packageName) {
13222         /* Only the shell, root, or the app user should be able to dump profiles. */
13223         final int callingUid = Binder.getCallingUid();
13224         final String[] callerPackageNames = getPackagesForUid(callingUid);
13225         if (callingUid != Process.SHELL_UID
13226                 && callingUid != Process.ROOT_UID
13227                 && !ArrayUtils.contains(callerPackageNames, packageName)) {
13228             throw new SecurityException("dumpProfiles");
13229         }
13230 
13231         AndroidPackage pkg;
13232         synchronized (mLock) {
13233             pkg = mPackages.get(packageName);
13234             if (pkg == null) {
13235                 throw new IllegalArgumentException("Unknown package: " + packageName);
13236             }
13237         }
13238 
13239         synchronized (mInstallLock) {
13240             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
13241             mArtManagerService.dumpProfiles(pkg);
13242             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13243         }
13244     }
13245 
13246     @Override
forceDexOpt(String packageName)13247     public void forceDexOpt(String packageName) {
13248         enforceSystemOrRoot("forceDexOpt");
13249 
13250         AndroidPackage pkg;
13251         PackageSetting pkgSetting;
13252         synchronized (mLock) {
13253             pkg = mPackages.get(packageName);
13254             pkgSetting = mSettings.getPackageLPr(packageName);
13255             if (pkg == null || pkgSetting == null) {
13256                 throw new IllegalArgumentException("Unknown package: " + packageName);
13257             }
13258         }
13259 
13260         synchronized (mInstallLock) {
13261             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
13262 
13263             // Whoever is calling forceDexOpt wants a compiled package.
13264             // Don't use profiles since that may cause compilation to be skipped.
13265             final int res = performDexOptInternalWithDependenciesLI(pkg, pkgSetting,
13266                     new DexoptOptions(packageName,
13267                             getDefaultCompilerFilter(),
13268                             DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
13269 
13270             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13271             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
13272                 throw new IllegalStateException("Failed to dexopt: " + res);
13273             }
13274         }
13275     }
13276 
13277     @GuardedBy("mLock")
verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg)13278     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) {
13279         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
13280             Slog.w(TAG, "Unable to update from " + oldPkg.name
13281                     + " to " + newPkg.getPackageName()
13282                     + ": old package not in system partition");
13283             return false;
13284         } else if (mPackages.get(oldPkg.name) != null) {
13285             Slog.w(TAG, "Unable to update from " + oldPkg.name
13286                     + " to " + newPkg.getPackageName()
13287                     + ": old package still exists");
13288             return false;
13289         }
13290         return true;
13291     }
13292 
13293     @GuardedBy("mInstallLock")
removeCodePathLI(File codePath)13294     void removeCodePathLI(File codePath) {
13295         if (codePath.isDirectory()) {
13296             final File codePathParent = codePath.getParentFile();
13297             final boolean needRemoveParent = codePathParent.getName().startsWith(RANDOM_DIR_PREFIX);
13298             try {
13299                 final boolean isIncremental = (mIncrementalManager != null && isIncrementalPath(
13300                         codePath.getAbsolutePath()));
13301                 if (isIncremental) {
13302                     if (needRemoveParent) {
13303                         mIncrementalManager.rmPackageDir(codePathParent);
13304                     } else {
13305                         mIncrementalManager.rmPackageDir(codePath);
13306                     }
13307                 }
13308 
13309                 mInstaller.rmPackageDir(codePath.getAbsolutePath());
13310                 if (needRemoveParent) {
13311                     mInstaller.rmPackageDir(codePathParent.getAbsolutePath());
13312                     removeCachedResult(codePathParent);
13313                 }
13314             } catch (InstallerException e) {
13315                 Slog.w(TAG, "Failed to remove code path", e);
13316             }
13317         } else {
13318             codePath.delete();
13319         }
13320     }
13321 
removeCachedResult(@onNull File codePath)13322     private void removeCachedResult(@NonNull File codePath) {
13323         if (mCacheDir == null) {
13324             return;
13325         }
13326 
13327         final PackageCacher cacher = new PackageCacher(mCacheDir);
13328         // Find and delete the cached result belong to the given codePath.
13329         cacher.cleanCachedResult(codePath);
13330     }
13331 
resolveUserIds(int userId)13332     private int[] resolveUserIds(int userId) {
13333         return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId };
13334     }
13335 
clearAppDataLIF(AndroidPackage pkg, int userId, int flags)13336     private void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) {
13337         if (pkg == null) {
13338             return;
13339         }
13340         clearAppDataLeafLIF(pkg, userId, flags);
13341 
13342         if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
13343             clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
13344         }
13345     }
13346 
clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags)13347     private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
13348         final PackageSetting ps;
13349         synchronized (mLock) {
13350             ps = mSettings.getPackageLPr(pkg.getPackageName());
13351         }
13352         for (int realUserId : resolveUserIds(userId)) {
13353             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
13354             try {
13355                 mInstaller.clearAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
13356                         flags, ceDataInode);
13357             } catch (InstallerException e) {
13358                 Slog.w(TAG, String.valueOf(e));
13359             }
13360         }
13361     }
13362 
destroyAppDataLIF(AndroidPackage pkg, int userId, int flags)13363     private void destroyAppDataLIF(AndroidPackage pkg, int userId, int flags) {
13364         if (pkg == null) {
13365             Slog.wtf(TAG, "Package was null!", new Throwable());
13366             return;
13367         }
13368         destroyAppDataLeafLIF(pkg, userId, flags);
13369     }
13370 
destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags)13371     private void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
13372         final PackageSetting ps;
13373         synchronized (mLock) {
13374             ps = mSettings.getPackageLPr(pkg.getPackageName());
13375         }
13376         for (int realUserId : resolveUserIds(userId)) {
13377             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
13378             try {
13379                 mInstaller.destroyAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
13380                         flags, ceDataInode);
13381             } catch (InstallerException e) {
13382                 Slog.w(TAG, String.valueOf(e));
13383             }
13384             mDexManager.notifyPackageDataDestroyed(pkg.getPackageName(), userId);
13385         }
13386     }
13387 
destroyAppProfilesLIF(AndroidPackage pkg)13388     private void destroyAppProfilesLIF(AndroidPackage pkg) {
13389         if (pkg == null) {
13390             Slog.wtf(TAG, "Package was null!", new Throwable());
13391             return;
13392         }
13393         destroyAppProfilesLeafLIF(pkg);
13394     }
13395 
destroyAppProfilesLeafLIF(AndroidPackage pkg)13396     private void destroyAppProfilesLeafLIF(AndroidPackage pkg) {
13397         try {
13398             mInstaller.destroyAppProfiles(pkg.getPackageName());
13399         } catch (InstallerException e) {
13400             Slog.w(TAG, String.valueOf(e));
13401         }
13402     }
13403 
clearAppProfilesLIF(AndroidPackage pkg, int userId)13404     private void clearAppProfilesLIF(AndroidPackage pkg, int userId) {
13405         if (pkg == null) {
13406             Slog.wtf(TAG, "Package was null!", new Throwable());
13407             return;
13408         }
13409         mArtManagerService.clearAppProfiles(pkg);
13410     }
13411 
13412     @GuardedBy("mLock")
applyDefiningSharedLibraryUpdateLocked( AndroidPackage pkg, SharedLibraryInfo libInfo, BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action)13413     private void applyDefiningSharedLibraryUpdateLocked(
13414             AndroidPackage pkg, SharedLibraryInfo libInfo,
13415             BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) {
13416         // Note that libraries defined by this package may be null if:
13417         // - Package manager was unable to create the shared library. The package still
13418         //   gets installed, but the shared library does not get created.
13419         // Or:
13420         // - Package manager is in a state where package isn't scanned yet. This will
13421         //   get called again after scanning to fix the dependencies.
13422         if (AndroidPackageUtils.isLibrary(pkg)) {
13423             if (pkg.getStaticSharedLibName() != null) {
13424                 SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
13425                         pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
13426                 if (definedLibrary != null) {
13427                     action.accept(definedLibrary, libInfo);
13428                 }
13429             } else {
13430                 for (String libraryName : pkg.getLibraryNames()) {
13431                     SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
13432                             libraryName, SharedLibraryInfo.VERSION_UNDEFINED);
13433                     if (definedLibrary != null) {
13434                         action.accept(definedLibrary, libInfo);
13435                     }
13436                 }
13437             }
13438         }
13439     }
13440 
13441     @GuardedBy("mLock")
addSharedLibraryLPr(AndroidPackage pkg, Set<String> usesLibraryFiles, SharedLibraryInfo libInfo, @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting)13442     private void addSharedLibraryLPr(AndroidPackage pkg, Set<String> usesLibraryFiles,
13443             SharedLibraryInfo libInfo, @Nullable AndroidPackage changingLib,
13444             @Nullable PackageSetting changingLibSetting) {
13445         if (libInfo.getPath() != null) {
13446             usesLibraryFiles.add(libInfo.getPath());
13447             return;
13448         }
13449         AndroidPackage pkgForCodePaths = mPackages.get(libInfo.getPackageName());
13450         PackageSetting pkgSetting = mSettings.getPackageLPr(libInfo.getPackageName());
13451         if (changingLib != null && changingLib.getPackageName().equals(libInfo.getPackageName())) {
13452             // If we are doing this while in the middle of updating a library apk,
13453             // then we need to make sure to use that new apk for determining the
13454             // dependencies here.  (We haven't yet finished committing the new apk
13455             // to the package manager state.)
13456             if (pkgForCodePaths == null
13457                     || pkgForCodePaths.getPackageName().equals(changingLib.getPackageName())) {
13458                 pkgForCodePaths = changingLib;
13459                 pkgSetting = changingLibSetting;
13460             }
13461         }
13462         if (pkgForCodePaths != null) {
13463             usesLibraryFiles.addAll(AndroidPackageUtils.getAllCodePaths(pkgForCodePaths));
13464             // If the package provides libraries, add the dependency to them.
13465             applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, SharedLibraryInfo::addDependency);
13466             if (pkgSetting != null) {
13467                 usesLibraryFiles.addAll(pkgSetting.getPkgState().getUsesLibraryFiles());
13468             }
13469         }
13470     }
13471 
13472     @GuardedBy("mLock")
updateSharedLibrariesLocked(AndroidPackage pkg, PackageSetting pkgSetting, @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting, Map<String, AndroidPackage> availablePackages)13473     private void updateSharedLibrariesLocked(AndroidPackage pkg, PackageSetting pkgSetting,
13474             @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting,
13475             Map<String, AndroidPackage> availablePackages)
13476             throws PackageManagerException {
13477         final ArrayList<SharedLibraryInfo> sharedLibraryInfos = collectSharedLibraryInfos(
13478                 pkgSetting.pkg, availablePackages, mSharedLibraries, null /* newLibraries */,
13479                 mInjector.getCompatibility());
13480         executeSharedLibrariesUpdateLPr(pkg, pkgSetting, changingLib, changingLibSetting,
13481                 sharedLibraryInfos, mUserManager.getUserIds());
13482     }
13483 
collectSharedLibraryInfos(AndroidPackage pkg, Map<String, AndroidPackage> availablePackages, @NonNull final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries, PlatformCompat platformCompat)13484     private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(AndroidPackage pkg,
13485             Map<String, AndroidPackage> availablePackages,
13486             @NonNull final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries,
13487             @Nullable final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries,
13488             PlatformCompat platformCompat) throws PackageManagerException {
13489         if (pkg == null) {
13490             return null;
13491         }
13492         // The collection used here must maintain the order of addition (so
13493         // that libraries are searched in the correct order) and must have no
13494         // duplicates.
13495         ArrayList<SharedLibraryInfo> usesLibraryInfos = null;
13496         if (!pkg.getUsesLibraries().isEmpty()) {
13497             usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null,
13498                     pkg.getPackageName(), true, pkg.getTargetSdkVersion(), null,
13499                     availablePackages, existingLibraries, newLibraries);
13500         }
13501         if (!pkg.getUsesStaticLibraries().isEmpty()) {
13502             usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(),
13503                     pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(),
13504                     pkg.getPackageName(), true, pkg.getTargetSdkVersion(), usesLibraryInfos,
13505                     availablePackages, existingLibraries, newLibraries);
13506         }
13507         if (!pkg.getUsesOptionalLibraries().isEmpty()) {
13508             usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(),
13509                     null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
13510                     usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
13511         }
13512         if (platformCompat.isChangeEnabledInternal(ENFORCE_NATIVE_SHARED_LIBRARY_DEPENDENCIES,
13513                 pkg.getPackageName(), pkg.getTargetSdkVersion())) {
13514             if (!pkg.getUsesNativeLibraries().isEmpty()) {
13515                 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesNativeLibraries(), null,
13516                         null, pkg.getPackageName(), true, pkg.getTargetSdkVersion(),
13517                         usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
13518             }
13519             if (!pkg.getUsesOptionalNativeLibraries().isEmpty()) {
13520                 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalNativeLibraries(),
13521                         null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
13522                         usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
13523             }
13524         }
13525         return usesLibraryInfos;
13526     }
13527 
executeSharedLibrariesUpdateLPr(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting, ArrayList<SharedLibraryInfo> usesLibraryInfos, int[] allUsers)13528     private void executeSharedLibrariesUpdateLPr(AndroidPackage pkg,
13529             @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib,
13530             @Nullable PackageSetting changingLibSetting,
13531             ArrayList<SharedLibraryInfo> usesLibraryInfos, int[] allUsers) {
13532         // If the package provides libraries, clear their old dependencies.
13533         // This method will set them up again.
13534         applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> {
13535             definingLibrary.clearDependencies();
13536         });
13537         if (usesLibraryInfos != null) {
13538             pkgSetting.getPkgState().setUsesLibraryInfos(usesLibraryInfos);
13539             // Use LinkedHashSet to preserve the order of files added to
13540             // usesLibraryFiles while eliminating duplicates.
13541             Set<String> usesLibraryFiles = new LinkedHashSet<>();
13542             for (SharedLibraryInfo libInfo : usesLibraryInfos) {
13543                 addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib,
13544                         changingLibSetting);
13545             }
13546             pkgSetting.getPkgState().setUsesLibraryFiles(new ArrayList<>(usesLibraryFiles));
13547             // let's make sure we mark all static shared libraries as installed for the same users
13548             // that its dependent packages are installed for.
13549             int[] installedUsers = new int[allUsers.length];
13550             int installedUserCount = 0;
13551             for (int u = 0; u < allUsers.length; u++) {
13552                 if (pkgSetting.getInstalled(allUsers[u])) {
13553                     installedUsers[installedUserCount++] = allUsers[u];
13554                 }
13555             }
13556             for (SharedLibraryInfo sharedLibraryInfo : usesLibraryInfos) {
13557                 if (!sharedLibraryInfo.isStatic()) {
13558                     continue;
13559                 }
13560                 final PackageSetting staticLibPkgSetting =
13561                         getPackageSetting(sharedLibraryInfo.getPackageName());
13562                 if (staticLibPkgSetting == null) {
13563                     Slog.wtf(TAG, "Shared lib without setting: " + sharedLibraryInfo);
13564                     continue;
13565                 }
13566                 for (int u = 0; u < installedUserCount; u++) {
13567                     staticLibPkgSetting.setInstalled(true, installedUsers[u]);
13568                 }
13569             }
13570         } else {
13571             pkgSetting.getPkgState().setUsesLibraryInfos(Collections.emptyList())
13572                     .setUsesLibraryFiles(Collections.emptyList());
13573         }
13574     }
13575 
13576     @GuardedBy("mLock")
collectSharedLibraryInfos( @onNull List<String> requestedLibraries, @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests, @NonNull String packageName, boolean required, int targetSdk, @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries, @NonNull final Map<String, AndroidPackage> availablePackages, @NonNull final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries)13577     private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(
13578             @NonNull List<String> requestedLibraries,
13579             @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
13580             @NonNull String packageName, boolean required, int targetSdk,
13581             @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries,
13582             @NonNull final Map<String, AndroidPackage> availablePackages,
13583             @NonNull final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries,
13584             @Nullable final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries)
13585             throws PackageManagerException {
13586         final int libCount = requestedLibraries.size();
13587         for (int i = 0; i < libCount; i++) {
13588             final String libName = requestedLibraries.get(i);
13589             final long libVersion = requiredVersions != null ? requiredVersions[i]
13590                     : SharedLibraryInfo.VERSION_UNDEFINED;
13591             final SharedLibraryInfo libraryInfo = getSharedLibraryInfo(libName, libVersion,
13592                     existingLibraries, newLibraries);
13593             if (libraryInfo == null) {
13594                 if (required) {
13595                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13596                             "Package " + packageName + " requires unavailable shared library "
13597                                     + libName + "; failing!");
13598                 } else if (DEBUG_SHARED_LIBRARIES) {
13599                     Slog.i(TAG, "Package " + packageName
13600                             + " desires unavailable shared library "
13601                             + libName + "; ignoring!");
13602                 }
13603             } else {
13604                 if (requiredVersions != null && requiredCertDigests != null) {
13605                     if (libraryInfo.getLongVersion() != requiredVersions[i]) {
13606                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13607                             "Package " + packageName + " requires unavailable static shared"
13608                                     + " library " + libName + " version "
13609                                     + libraryInfo.getLongVersion() + "; failing!");
13610                     }
13611                     AndroidPackage pkg = availablePackages.get(libraryInfo.getPackageName());
13612                     SigningDetails libPkg = pkg == null ? null : pkg.getSigningDetails();
13613                     if (libPkg == null) {
13614                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13615                                 "Package " + packageName + " requires unavailable static shared"
13616                                         + " library; failing!");
13617                     }
13618                     final String[] expectedCertDigests = requiredCertDigests[i];
13619                     if (expectedCertDigests.length > 1) {
13620                         // For apps targeting O MR1 we require explicit enumeration of all certs.
13621                         final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
13622                                 ? PackageUtils.computeSignaturesSha256Digests(
13623                                 libPkg.signatures)
13624                                 : PackageUtils.computeSignaturesSha256Digests(
13625                                         new Signature[]{libPkg.signatures[0]});
13626 
13627                         // Take a shortcut if sizes don't match. Note that if an app doesn't
13628                         // target O we don't parse the "additional-certificate" tags similarly
13629                         // how we only consider all certs only for apps targeting O (see above).
13630                         // Therefore, the size check is safe to make.
13631                         if (expectedCertDigests.length != libCertDigests.length) {
13632                             throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13633                                     "Package " + packageName + " requires differently signed" +
13634                                             " static shared library; failing!");
13635                         }
13636 
13637                         // Use a predictable order as signature order may vary
13638                         Arrays.sort(libCertDigests);
13639                         Arrays.sort(expectedCertDigests);
13640 
13641                         final int certCount = libCertDigests.length;
13642                         for (int j = 0; j < certCount; j++) {
13643                             if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
13644                                 throw new PackageManagerException(
13645                                         INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13646                                         "Package " + packageName + " requires differently signed" +
13647                                                 " static shared library; failing!");
13648                             }
13649                         }
13650                     } else {
13651                         // lib signing cert could have rotated beyond the one expected, check to see
13652                         // if the new one has been blessed by the old
13653                         byte[] digestBytes = HexEncoding.decode(
13654                                 expectedCertDigests[0], false /* allowSingleChar */);
13655                         if (!libPkg.hasSha256Certificate(digestBytes)) {
13656                             throw new PackageManagerException(
13657                                     INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13658                                     "Package " + packageName + " requires differently signed" +
13659                                             " static shared library; failing!");
13660                         }
13661                     }
13662                 }
13663                 if (outUsedLibraries == null) {
13664                     outUsedLibraries = new ArrayList<>();
13665                 }
13666                 outUsedLibraries.add(libraryInfo);
13667             }
13668         }
13669         return outUsedLibraries;
13670     }
13671 
hasString(List<String> list, List<String> which)13672     private static boolean hasString(List<String> list, List<String> which) {
13673         if (list == null || which == null) {
13674             return false;
13675         }
13676         for (int i=list.size()-1; i>=0; i--) {
13677             for (int j=which.size()-1; j>=0; j--) {
13678                 if (which.get(j).equals(list.get(i))) {
13679                     return true;
13680                 }
13681             }
13682         }
13683         return false;
13684     }
13685 
13686     @GuardedBy("mLock")
updateAllSharedLibrariesLocked( @ullable AndroidPackage updatedPkg, @Nullable PackageSetting updatedPkgSetting, Map<String, AndroidPackage> availablePackages)13687     private ArrayList<AndroidPackage> updateAllSharedLibrariesLocked(
13688             @Nullable AndroidPackage updatedPkg, @Nullable PackageSetting updatedPkgSetting,
13689             Map<String, AndroidPackage> availablePackages) {
13690         ArrayList<AndroidPackage> resultList = null;
13691         // Set of all descendants of a library; used to eliminate cycles
13692         ArraySet<String> descendants = null;
13693         // The current list of packages that need updating
13694         List<Pair<AndroidPackage, PackageSetting>> needsUpdating = null;
13695         if (updatedPkg != null && updatedPkgSetting != null) {
13696             needsUpdating = new ArrayList<>(1);
13697             needsUpdating.add(Pair.create(updatedPkg, updatedPkgSetting));
13698         }
13699         do {
13700             final Pair<AndroidPackage, PackageSetting> changingPkgPair =
13701                     (needsUpdating == null) ? null : needsUpdating.remove(0);
13702             final AndroidPackage changingPkg = changingPkgPair != null
13703                     ? changingPkgPair.first : null;
13704             final PackageSetting changingPkgSetting = changingPkgPair != null
13705                     ? changingPkgPair.second : null;
13706             for (int i = mPackages.size() - 1; i >= 0; --i) {
13707                 final AndroidPackage pkg = mPackages.valueAt(i);
13708                 final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
13709                 if (changingPkg != null
13710                         && !hasString(pkg.getUsesLibraries(), changingPkg.getLibraryNames())
13711                         && !hasString(pkg.getUsesOptionalLibraries(), changingPkg.getLibraryNames())
13712                         && !ArrayUtils.contains(pkg.getUsesStaticLibraries(),
13713                         changingPkg.getStaticSharedLibName())) {
13714                     continue;
13715                 }
13716                 if (resultList == null) {
13717                     resultList = new ArrayList<>();
13718                 }
13719                 resultList.add(pkg);
13720                 // if we're updating a shared library, all of its descendants must be updated
13721                 if (changingPkg != null) {
13722                     if (descendants == null) {
13723                         descendants = new ArraySet<>();
13724                     }
13725                     if (!descendants.contains(pkg.getPackageName())) {
13726                         descendants.add(pkg.getPackageName());
13727                         needsUpdating.add(Pair.create(pkg, pkgSetting));
13728                     }
13729                 }
13730                 try {
13731                     updateSharedLibrariesLocked(pkg, pkgSetting, changingPkg,
13732                             changingPkgSetting, availablePackages);
13733                 } catch (PackageManagerException e) {
13734                     // If a system app update or an app and a required lib missing we
13735                     // delete the package and for updated system apps keep the data as
13736                     // it is better for the user to reinstall than to be in an limbo
13737                     // state. Also libs disappearing under an app should never happen
13738                     // - just in case.
13739                     if (!pkg.isSystem() || pkgSetting.getPkgState().isUpdatedSystemApp()) {
13740                         final int flags = pkgSetting.getPkgState().isUpdatedSystemApp()
13741                                 ? PackageManager.DELETE_KEEP_DATA : 0;
13742                         deletePackageLIF(pkg.getPackageName(), null, true,
13743                                 mUserManager.getUserIds(), flags, null,
13744                                 true, null);
13745                     }
13746                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
13747                 }
13748             }
13749         } while (needsUpdating != null && needsUpdating.size() > 0);
13750         return resultList;
13751     }
13752 
getVendorPartitionVersion()13753     private int getVendorPartitionVersion() {
13754         final String version = SystemProperties.get("ro.vndk.version");
13755         if (!version.isEmpty()) {
13756             try {
13757                 return Integer.parseInt(version);
13758             } catch (NumberFormatException ignore) {
13759                 if (ArrayUtils.contains(Build.VERSION.ACTIVE_CODENAMES, version)) {
13760                     return Build.VERSION_CODES.CUR_DEVELOPMENT;
13761                 }
13762             }
13763         }
13764         return Build.VERSION_CODES.P;
13765     }
13766 
13767     @GuardedBy({"mInstallLock", "mLock"})
scanPackageTracedLI(ParsedPackage parsedPackage, final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user, String cpuAbiOverride)13768     private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
13769             final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
13770             @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
13771         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
13772         try {
13773             return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user,
13774                     cpuAbiOverride);
13775         } finally {
13776             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13777         }
13778     }
13779 
13780     /** The result of a package scan. */
13781     @VisibleForTesting
13782     static class ScanResult {
13783         /** The request that initiated the scan that produced this result. */
13784         public final ScanRequest request;
13785         /** Whether or not the package scan was successful */
13786         public final boolean success;
13787         /**
13788          * Whether or not the original PackageSetting needs to be updated with this result on
13789          * commit.
13790          */
13791         public final boolean existingSettingCopied;
13792         /**
13793          * The final package settings. This may be the same object passed in
13794          * the {@link ScanRequest}, but, with modified values.
13795          */
13796         @Nullable public final PackageSetting pkgSetting;
13797         /** ABI code paths that have changed in the package scan */
13798         @Nullable public final List<String> changedAbiCodePath;
13799 
13800         public final SharedLibraryInfo staticSharedLibraryInfo;
13801 
13802         public final List<SharedLibraryInfo> dynamicSharedLibraryInfos;
13803 
ScanResult( ScanRequest request, boolean success, @Nullable PackageSetting pkgSetting, @Nullable List<String> changedAbiCodePath, boolean existingSettingCopied, SharedLibraryInfo staticSharedLibraryInfo, List<SharedLibraryInfo> dynamicSharedLibraryInfos)13804         public ScanResult(
13805                 ScanRequest request, boolean success,
13806                 @Nullable PackageSetting pkgSetting,
13807                 @Nullable List<String> changedAbiCodePath, boolean existingSettingCopied,
13808                 SharedLibraryInfo staticSharedLibraryInfo,
13809                 List<SharedLibraryInfo> dynamicSharedLibraryInfos) {
13810             this.request = request;
13811             this.success = success;
13812             this.pkgSetting = pkgSetting;
13813             this.changedAbiCodePath = changedAbiCodePath;
13814             this.existingSettingCopied = existingSettingCopied;
13815             this.staticSharedLibraryInfo = staticSharedLibraryInfo;
13816             this.dynamicSharedLibraryInfos = dynamicSharedLibraryInfos;
13817         }
13818     }
13819 
13820     /** A package to be scanned */
13821     @VisibleForTesting
13822     static class ScanRequest {
13823         /** The parsed package */
13824         @NonNull public final ParsedPackage parsedPackage;
13825         /** The package this package replaces */
13826         @Nullable public final AndroidPackage oldPkg;
13827         /** Shared user settings, if the package has a shared user */
13828         @Nullable public final SharedUserSetting sharedUserSetting;
13829         /**
13830          * Package settings of the currently installed version.
13831          * <p><em>IMPORTANT:</em> The contents of this object may be modified
13832          * during scan.
13833          */
13834         @Nullable public final PackageSetting pkgSetting;
13835         /** A copy of the settings for the currently installed version */
13836         @Nullable public final PackageSetting oldPkgSetting;
13837         /** Package settings for the disabled version on the /system partition */
13838         @Nullable public final PackageSetting disabledPkgSetting;
13839         /** Package settings for the installed version under its original package name */
13840         @Nullable public final PackageSetting originalPkgSetting;
13841         /** The real package name of a renamed application */
13842         @Nullable public final String realPkgName;
13843         public final @ParseFlags int parseFlags;
13844         public final @ScanFlags int scanFlags;
13845         /** The user for which the package is being scanned */
13846         @Nullable public final UserHandle user;
13847         /** Whether or not the platform package is being scanned */
13848         public final boolean isPlatformPackage;
13849         /** Override value for package ABI if set during install */
13850         @Nullable
13851         public final String cpuAbiOverride;
ScanRequest( @onNull ParsedPackage parsedPackage, @Nullable SharedUserSetting sharedUserSetting, @Nullable AndroidPackage oldPkg, @Nullable PackageSetting pkgSetting, @Nullable PackageSetting disabledPkgSetting, @Nullable PackageSetting originalPkgSetting, @Nullable String realPkgName, @ParseFlags int parseFlags, @ScanFlags int scanFlags, boolean isPlatformPackage, @Nullable UserHandle user, @Nullable String cpuAbiOverride)13852         public ScanRequest(
13853                 @NonNull ParsedPackage parsedPackage,
13854                 @Nullable SharedUserSetting sharedUserSetting,
13855                 @Nullable AndroidPackage oldPkg,
13856                 @Nullable PackageSetting pkgSetting,
13857                 @Nullable PackageSetting disabledPkgSetting,
13858                 @Nullable PackageSetting originalPkgSetting,
13859                 @Nullable String realPkgName,
13860                 @ParseFlags int parseFlags,
13861                 @ScanFlags int scanFlags,
13862                 boolean isPlatformPackage,
13863                 @Nullable UserHandle user,
13864                 @Nullable String cpuAbiOverride) {
13865             this.parsedPackage = parsedPackage;
13866             this.oldPkg = oldPkg;
13867             this.pkgSetting = pkgSetting;
13868             this.sharedUserSetting = sharedUserSetting;
13869             this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
13870             this.disabledPkgSetting = disabledPkgSetting;
13871             this.originalPkgSetting = originalPkgSetting;
13872             this.realPkgName = realPkgName;
13873             this.parseFlags = parseFlags;
13874             this.scanFlags = scanFlags;
13875             this.isPlatformPackage = isPlatformPackage;
13876             this.user = user;
13877             this.cpuAbiOverride = cpuAbiOverride;
13878         }
13879     }
13880 
13881     /**
13882      * Returns the actual scan flags depending upon the state of the other settings.
13883      * <p>Updated system applications will not have the following flags set
13884      * by default and need to be adjusted after the fact:
13885      * <ul>
13886      * <li>{@link #SCAN_AS_SYSTEM}</li>
13887      * <li>{@link #SCAN_AS_PRIVILEGED}</li>
13888      * <li>{@link #SCAN_AS_OEM}</li>
13889      * <li>{@link #SCAN_AS_VENDOR}</li>
13890      * <li>{@link #SCAN_AS_PRODUCT}</li>
13891      * <li>{@link #SCAN_AS_SYSTEM_EXT}</li>
13892      * <li>{@link #SCAN_AS_INSTANT_APP}</li>
13893      * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
13894      * <li>{@link #SCAN_AS_ODM}</li>
13895      * </ul>
13896      */
adjustScanFlags(@canFlags int scanFlags, PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user, AndroidPackage pkg)13897     private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
13898             PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
13899             AndroidPackage pkg) {
13900 
13901         // TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain
13902         // the correct isSystem value now that we don't disable system packages before scan.
13903         final PackageSetting systemPkgSetting =
13904                 (scanFlags & SCAN_NEW_INSTALL) != 0 && disabledPkgSetting == null
13905                         && pkgSetting != null && pkgSetting.isSystem()
13906                         ? pkgSetting
13907                         : disabledPkgSetting;
13908         if (systemPkgSetting != null)  {
13909             // updated system application, must at least have SCAN_AS_SYSTEM
13910             scanFlags |= SCAN_AS_SYSTEM;
13911             if ((systemPkgSetting.pkgPrivateFlags
13912                     & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
13913                 scanFlags |= SCAN_AS_PRIVILEGED;
13914             }
13915             if ((systemPkgSetting.pkgPrivateFlags
13916                     & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
13917                 scanFlags |= SCAN_AS_OEM;
13918             }
13919             if ((systemPkgSetting.pkgPrivateFlags
13920                     & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
13921                 scanFlags |= SCAN_AS_VENDOR;
13922             }
13923             if ((systemPkgSetting.pkgPrivateFlags
13924                     & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
13925                 scanFlags |= SCAN_AS_PRODUCT;
13926             }
13927             if ((systemPkgSetting.pkgPrivateFlags
13928                     & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
13929                 scanFlags |= SCAN_AS_SYSTEM_EXT;
13930             }
13931             if ((systemPkgSetting.pkgPrivateFlags
13932                     & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
13933                 scanFlags |= SCAN_AS_ODM;
13934             }
13935         }
13936         if (pkgSetting != null) {
13937             final int userId = ((user == null) ? 0 : user.getIdentifier());
13938             if (pkgSetting.getInstantApp(userId)) {
13939                 scanFlags |= SCAN_AS_INSTANT_APP;
13940             }
13941             if (pkgSetting.getVirtulalPreload(userId)) {
13942                 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
13943             }
13944         }
13945 
13946         // Scan as privileged apps that share a user with a priv-app.
13947         final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
13948                 && getVendorPartitionVersion() < 28;
13949         if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
13950                 && !pkg.isPrivileged()
13951                 && (pkg.getSharedUserId() != null)
13952                 && !skipVendorPrivilegeScan) {
13953             SharedUserSetting sharedUserSetting = null;
13954             try {
13955                 sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0,
13956                         0, false);
13957             } catch (PackageManagerException ignore) {
13958             }
13959             if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
13960                 // Exempt SharedUsers signed with the platform key.
13961                 // TODO(b/72378145) Fix this exemption. Force signature apps
13962                 // to allowlist their privileged permissions just like other
13963                 // priv-apps.
13964                 synchronized (mLock) {
13965                     PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
13966                     if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
13967                             pkg.getSigningDetails().signatures)
13968                             != PackageManager.SIGNATURE_MATCH)) {
13969                         scanFlags |= SCAN_AS_PRIVILEGED;
13970                     }
13971                 }
13972             }
13973         }
13974 
13975         return scanFlags;
13976     }
13977 
13978     // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting
13979     // the results / removing app data needs to be moved up a level to the callers of this
13980     // method. Also, we need to solve the problem of potentially creating a new shared user
13981     // setting. That can probably be done later and patch things up after the fact.
13982     @GuardedBy({"mInstallLock", "mLock"})
13983     private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
13984             final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
13985             @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
13986 
13987         final String renamedPkgName = mSettings.getRenamedPackageLPr(
13988                 parsedPackage.getRealPackage());
13989         final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
13990         if (realPkgName != null) {
13991             ensurePackageRenamed(parsedPackage, renamedPkgName);
13992         }
13993         final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
13994                 renamedPkgName);
13995         final PackageSetting pkgSetting = mSettings.getPackageLPr(parsedPackage.getPackageName());
13996         final PackageSetting disabledPkgSetting =
13997                 mSettings.getDisabledSystemPkgLPr(parsedPackage.getPackageName());
13998 
13999         if (mTransferredPackages.contains(parsedPackage.getPackageName())) {
14000             Slog.w(TAG, "Package " + parsedPackage.getPackageName()
14001                     + " was transferred to another, but its .apk remains");
14002         }
14003 
14004         scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, parsedPackage);
14005         synchronized (mLock) {
14006             boolean isUpdatedSystemApp;
14007             if (pkgSetting != null) {
14008                 isUpdatedSystemApp = pkgSetting.getPkgState().isUpdatedSystemApp();
14009             } else {
14010                 isUpdatedSystemApp = disabledPkgSetting != null;
14011             }
14012             applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp);
14013             assertPackageIsValid(parsedPackage, parseFlags, scanFlags);
14014 
14015             SharedUserSetting sharedUserSetting = null;
14016             if (parsedPackage.getSharedUserId() != null) {
14017                 // SIDE EFFECTS; may potentially allocate a new shared user
14018                 sharedUserSetting = mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
14019                         0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
14020                 if (DEBUG_PACKAGE_SCANNING) {
14021                     if ((parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0) {
14022                         Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
14023                                 + " (uid=" + sharedUserSetting.userId + "):"
14024                                 + " packages=" + sharedUserSetting.packages);
14025                     }
14026                 }
14027             }
14028             String platformPackageName = mPlatformPackage == null
14029                     ? null : mPlatformPackage.getPackageName();
14030             final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
14031                     pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
14032                     originalPkgSetting, realPkgName, parseFlags, scanFlags,
14033                     Objects.equals(parsedPackage.getPackageName(), platformPackageName), user,
14034                     cpuAbiOverride);
14035             return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime);
14036         }
14037     }
14038 
14039 
14040     /**
14041      * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering
14042      * the app ID required for reconcile.
14043      * @return {@code true} if a new app ID was registered and will need to be cleaned up on
14044      *         failure.
14045      */
14046     private boolean optimisticallyRegisterAppId(@NonNull ScanResult result)
14047             throws PackageManagerException {
14048         if (!result.existingSettingCopied) {
14049             // THROWS: when we can't allocate a user id. add call to check if there's
14050             // enough space to ensure we won't throw; otherwise, don't modify state
14051             return mSettings.registerAppIdLPw(result.pkgSetting);
14052         }
14053         return false;
14054     }
14055 
14056     /**
14057      * Reverts any app ID creation that were made by
14058      * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
14059      * referenced method returned true.
14060      */
14061     private void cleanUpAppIdCreation(@NonNull ScanResult result) {
14062         // iff we've acquired an app ID for a new package setting, remove it so that it can be
14063         // acquired by another request.
14064         if (result.pkgSetting.appId > 0) {
14065             mSettings.removeAppIdLPw(result.pkgSetting.appId);
14066         }
14067     }
14068 
14069     /**
14070      * Commits the package scan and modifies system state.
14071      * <p><em>WARNING:</em> The method may throw an excpetion in the middle
14072      * of committing the package, leaving the system in an inconsistent state.
14073      * This needs to be fixed so, once we get to this point, no errors are
14074      * possible and the system is not left in an inconsistent state.
14075      */
14076     @GuardedBy({"mLock", "mInstallLock"})
14077     private AndroidPackage commitReconciledScanResultLocked(
14078             @NonNull ReconciledPackage reconciledPkg, int[] allUsers) {
14079         final ScanResult result = reconciledPkg.scanResult;
14080         final ScanRequest request = result.request;
14081         // TODO(b/135203078): Move this even further away
14082         ParsedPackage parsedPackage = request.parsedPackage;
14083         if ("android".equals(parsedPackage.getPackageName())) {
14084             // TODO(b/135203078): Move this to initial parse
14085             parsedPackage.setVersionCode(mSdkVersion)
14086                     .setVersionCodeMajor(0);
14087         }
14088 
14089         final AndroidPackage oldPkg = request.oldPkg;
14090         final @ParseFlags int parseFlags = request.parseFlags;
14091         final @ScanFlags int scanFlags = request.scanFlags;
14092         final PackageSetting oldPkgSetting = request.oldPkgSetting;
14093         final PackageSetting originalPkgSetting = request.originalPkgSetting;
14094         final UserHandle user = request.user;
14095         final String realPkgName = request.realPkgName;
14096         final List<String> changedAbiCodePath = result.changedAbiCodePath;
14097         final PackageSetting pkgSetting;
14098         if (request.pkgSetting != null && request.pkgSetting.sharedUser != null
14099                 && request.pkgSetting.sharedUser != result.pkgSetting.sharedUser) {
14100             // shared user changed, remove from old shared user
14101             request.pkgSetting.sharedUser.removePackage(request.pkgSetting);
14102         }
14103         if (result.existingSettingCopied) {
14104             pkgSetting = request.pkgSetting;
14105             pkgSetting.updateFrom(result.pkgSetting);
14106         } else {
14107             pkgSetting = result.pkgSetting;
14108             if (originalPkgSetting != null) {
14109                 mSettings.addRenamedPackageLPw(parsedPackage.getRealPackage(),
14110                         originalPkgSetting.name);
14111                 mTransferredPackages.add(originalPkgSetting.name);
14112             } else {
14113                 mSettings.removeRenamedPackageLPw(parsedPackage.getPackageName());
14114             }
14115         }
14116         if (pkgSetting.sharedUser != null) {
14117             pkgSetting.sharedUser.addPackage(pkgSetting);
14118         }
14119         if (reconciledPkg.installArgs != null && reconciledPkg.installArgs.forceQueryableOverride) {
14120             pkgSetting.forceQueryableOverride = true;
14121         }
14122 
14123         // If this is part of a standard install, set the initiating package name, else rely on
14124         // previous device state.
14125         if (reconciledPkg.installArgs != null) {
14126             InstallSource installSource = reconciledPkg.installArgs.installSource;
14127             if (installSource.initiatingPackageName != null) {
14128                 final PackageSetting ips = mSettings.getPackageLPr(
14129                         installSource.initiatingPackageName);
14130                 if (ips != null) {
14131                     installSource = installSource.setInitiatingPackageSignatures(
14132                             ips.signatures);
14133                 }
14134             }
14135             pkgSetting.setInstallSource(installSource);
14136         }
14137 
14138         // TODO(toddke): Consider a method specifically for modifying the Package object
14139         // post scan; or, moving this stuff out of the Package object since it has nothing
14140         // to do with the package on disk.
14141         // We need to have this here because addUserToSettingLPw() is sometimes responsible
14142         // for creating the application ID. If we did this earlier, we would be saving the
14143         // correct ID.
14144         parsedPackage.setUid(pkgSetting.appId);
14145         final AndroidPackage pkg = parsedPackage.hideAsFinal();
14146 
14147         mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
14148 
14149         if (realPkgName != null) {
14150             mTransferredPackages.add(pkg.getPackageName());
14151         }
14152 
14153         if (reconciledPkg.collectedSharedLibraryInfos != null) {
14154             executeSharedLibrariesUpdateLPr(pkg, pkgSetting, null, null,
14155                     reconciledPkg.collectedSharedLibraryInfos, allUsers);
14156         }
14157 
14158         final KeySetManagerService ksms = mSettings.getKeySetManagerService();
14159         if (reconciledPkg.removeAppKeySetData) {
14160             ksms.removeAppKeySetDataLPw(pkg.getPackageName());
14161         }
14162         if (reconciledPkg.sharedUserSignaturesChanged) {
14163             pkgSetting.sharedUser.signaturesChanged = Boolean.TRUE;
14164             pkgSetting.sharedUser.signatures.mSigningDetails = reconciledPkg.signingDetails;
14165         }
14166         pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails;
14167 
14168         if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
14169             for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
14170                 final String codePathString = changedAbiCodePath.get(i);
14171                 try {
14172                     mInstaller.rmdex(codePathString,
14173                             getDexCodeInstructionSet(getPreferredInstructionSet()));
14174                 } catch (InstallerException ignored) {
14175                 }
14176             }
14177         }
14178 
14179         final int userId = user == null ? 0 : user.getIdentifier();
14180         // Modify state for the given package setting
14181         commitPackageSettings(pkg, oldPkg, pkgSetting, oldPkgSetting, scanFlags,
14182                 (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
14183         if (pkgSetting.getInstantApp(userId)) {
14184             mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
14185         }
14186         pkgSetting.setStatesOnCommit();
14187 
14188         return pkg;
14189     }
14190 
14191     /**
14192      * Returns the "real" name of the package.
14193      * <p>This may differ from the package's actual name if the application has already
14194      * been installed under one of this package's original names.
14195      */
14196     private static @Nullable String getRealPackageName(@NonNull AndroidPackage pkg,
14197             @Nullable String renamedPkgName) {
14198         if (isPackageRenamed(pkg, renamedPkgName)) {
14199             return pkg.getRealPackage();
14200         }
14201         return null;
14202     }
14203 
14204     /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
14205     private static boolean isPackageRenamed(@NonNull AndroidPackage pkg,
14206             @Nullable String renamedPkgName) {
14207         return pkg.getOriginalPackages().contains(renamedPkgName);
14208     }
14209 
14210     /**
14211      * Returns the original package setting.
14212      * <p>A package can migrate its name during an update. In this scenario, a package
14213      * designates a set of names that it considers as one of its original names.
14214      * <p>An original package must be signed identically and it must have the same
14215      * shared user [if any].
14216      */
14217     @GuardedBy("mLock")
14218     private @Nullable PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg,
14219             @Nullable String renamedPkgName) {
14220         if (isPackageRenamed(pkg, renamedPkgName)) {
14221             return null;
14222         }
14223         for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) {
14224             final PackageSetting originalPs =
14225                     mSettings.getPackageLPr(pkg.getOriginalPackages().get(i));
14226             if (originalPs != null) {
14227                 // the package is already installed under its original name...
14228                 // but, should we use it?
14229                 if (!verifyPackageUpdateLPr(originalPs, pkg)) {
14230                     // the new package is incompatible with the original
14231                     continue;
14232                 } else if (originalPs.sharedUser != null) {
14233                     if (!originalPs.sharedUser.name.equals(pkg.getSharedUserId())) {
14234                         // the shared user id is incompatible with the original
14235                         Slog.w(TAG, "Unable to migrate data from " + originalPs.name
14236                                 + " to " + pkg.getPackageName() + ": old uid "
14237                                 + originalPs.sharedUser.name
14238                                 + " differs from " + pkg.getSharedUserId());
14239                         continue;
14240                     }
14241                     // TODO: Add case when shared user id is added [b/28144775]
14242                 } else {
14243                     if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
14244                             + pkg.getPackageName() + " to old name " + originalPs.name);
14245                 }
14246                 return originalPs;
14247             }
14248         }
14249         return null;
14250     }
14251 
14252     /**
14253      * Renames the package if it was installed under a different name.
14254      * <p>When we've already installed the package under an original name, update
14255      * the new package so we can continue to have the old name.
14256      */
14257     private static void ensurePackageRenamed(@NonNull ParsedPackage parsedPackage,
14258             @NonNull String renamedPackageName) {
14259         if (!parsedPackage.getOriginalPackages().contains(renamedPackageName)
14260                 || parsedPackage.getPackageName().equals(renamedPackageName)) {
14261             return;
14262         }
14263         parsedPackage.setPackageName(renamedPackageName);
14264     }
14265 
14266     /**
14267      * Applies the adjusted ABI calculated by
14268      * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, AndroidPackage)} to all
14269      * relevant packages and settings.
14270      * @param sharedUserSetting The {@code SharedUserSetting} to adjust
14271      * @param scannedPackage the package being scanned or null
14272      * @param adjustedAbi the adjusted ABI calculated by {@link PackageAbiHelper}
14273      * @return the list of code paths that belong to packages that had their ABIs adjusted.
14274      */
14275     private static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting,
14276             ParsedPackage scannedPackage, String adjustedAbi) {
14277         if (scannedPackage != null)  {
14278             scannedPackage.setPrimaryCpuAbi(adjustedAbi);
14279         }
14280         List<String> changedAbiCodePath = null;
14281         for (PackageSetting ps : sharedUserSetting.packages) {
14282             if (scannedPackage == null || !scannedPackage.getPackageName().equals(ps.name)) {
14283                 if (ps.primaryCpuAbiString != null) {
14284                     continue;
14285                 }
14286 
14287                 ps.primaryCpuAbiString = adjustedAbi;
14288                 if (ps.pkg != null) {
14289                     if (!TextUtils.equals(adjustedAbi,
14290                             AndroidPackageUtils.getRawPrimaryCpuAbi(ps.pkg))) {
14291                         if (DEBUG_ABI_SELECTION) {
14292                             Slog.i(TAG,
14293                                     "Adjusting ABI for " + ps.name + " to " + adjustedAbi
14294                                             + " (scannedPackage="
14295                                             + (scannedPackage != null ? scannedPackage : "null")
14296                                             + ")");
14297                         }
14298                         if (changedAbiCodePath == null) {
14299                             changedAbiCodePath = new ArrayList<>();
14300                         }
14301                         changedAbiCodePath.add(ps.getPathString());
14302                     }
14303                 }
14304             }
14305         }
14306         return changedAbiCodePath;
14307     }
14308 
14309     /**
14310      * Sets the enabled state of components configured through {@link SystemConfig}.
14311      * This modifies the {@link PackageSetting} object.
14312      *
14313      * TODO(b/135203078): Move this to package parsing
14314      **/
14315     static void configurePackageComponents(AndroidPackage pkg) {
14316         final ArrayMap<String, Boolean> componentsEnabledStates = SystemConfig.getInstance()
14317                 .getComponentsEnabledStates(pkg.getPackageName());
14318         if (componentsEnabledStates == null) {
14319             return;
14320         }
14321 
14322         for (int i = ArrayUtils.size(pkg.getActivities()) - 1; i >= 0; i--) {
14323             final ParsedActivity component = pkg.getActivities().get(i);
14324             final Boolean enabled = componentsEnabledStates.get(component.getName());
14325             if (enabled != null) {
14326                 component.setEnabled(enabled);
14327             }
14328         }
14329 
14330         for (int i = ArrayUtils.size(pkg.getReceivers()) - 1; i >= 0; i--) {
14331             final ParsedActivity component = pkg.getReceivers().get(i);
14332             final Boolean enabled = componentsEnabledStates.get(component.getName());
14333             if (enabled != null) {
14334                 component.setEnabled(enabled);
14335             }
14336         }
14337 
14338         for (int i = ArrayUtils.size(pkg.getProviders()) - 1; i >= 0; i--) {
14339             final ParsedProvider component = pkg.getProviders().get(i);
14340             final Boolean enabled = componentsEnabledStates.get(component.getName());
14341             if (enabled != null) {
14342                 component.setEnabled(enabled);
14343             }
14344         }
14345 
14346         for (int i = ArrayUtils.size(pkg.getServices()) - 1; i >= 0; i--) {
14347             final ParsedService component = pkg.getServices().get(i);
14348             final Boolean enabled = componentsEnabledStates.get(component.getName());
14349             if (enabled != null) {
14350                 component.setEnabled(enabled);
14351             }
14352         }
14353     }
14354 
14355 
14356     /**
14357      * Just scans the package without any side effects.
14358      * <p>Not entirely true at the moment. There is still one side effect -- this
14359      * method potentially modifies a live {@link PackageSetting} object representing
14360      * the package being scanned. This will be resolved in the future.
14361      *
14362      * @param injector injector for acquiring dependencies
14363      * @param request Information about the package to be scanned
14364      * @param isUnderFactoryTest Whether or not the device is under factory test
14365      * @param currentTime The current time, in millis
14366      * @return The results of the scan
14367      */
14368     @GuardedBy("mInstallLock")
14369     @VisibleForTesting
14370     @NonNull
14371     static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
14372             Injector injector,
14373             boolean isUnderFactoryTest, long currentTime)
14374             throws PackageManagerException {
14375         final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
14376         final UserManagerInternal userManager = injector.getUserManagerInternal();
14377         ParsedPackage parsedPackage = request.parsedPackage;
14378         PackageSetting pkgSetting = request.pkgSetting;
14379         final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
14380         final PackageSetting originalPkgSetting = request.originalPkgSetting;
14381         final @ParseFlags int parseFlags = request.parseFlags;
14382         final @ScanFlags int scanFlags = request.scanFlags;
14383         final String realPkgName = request.realPkgName;
14384         final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
14385         final UserHandle user = request.user;
14386         final boolean isPlatformPackage = request.isPlatformPackage;
14387 
14388         List<String> changedAbiCodePath = null;
14389 
14390         if (DEBUG_PACKAGE_SCANNING) {
14391             if ((parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0) {
14392                 Log.d(TAG, "Scanning package " + parsedPackage.getPackageName());
14393             }
14394         }
14395 
14396         // Initialize package source and resource directories
14397         final File destCodeFile = new File(parsedPackage.getPath());
14398 
14399         // We keep references to the derived CPU Abis from settings in oder to reuse
14400         // them in the case where we're not upgrading or booting for the first time.
14401         String primaryCpuAbiFromSettings = null;
14402         String secondaryCpuAbiFromSettings = null;
14403         boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
14404         if (!needToDeriveAbi) {
14405             if (pkgSetting != null) {
14406                 // TODO(b/154610922): if it is not first boot or upgrade, we should directly use
14407                 // API info from existing package setting. However, stub packages currently do not
14408                 // preserve ABI info, thus the special condition check here. Remove the special
14409                 // check after we fix the stub generation.
14410                 if (pkgSetting.pkg != null && pkgSetting.pkg.isStub()) {
14411                     needToDeriveAbi = true;
14412                 } else {
14413                     primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
14414                     secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
14415                 }
14416             } else {
14417                 // Re-scanning a system package after uninstalling updates; need to derive ABI
14418                 needToDeriveAbi = true;
14419             }
14420         }
14421 
14422         if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
14423             PackageManagerService.reportSettingsProblem(Log.WARN,
14424                     "Package " + parsedPackage.getPackageName() + " shared user changed from "
14425                             + (pkgSetting.sharedUser != null
14426                             ? pkgSetting.sharedUser.name : "<nothing>")
14427                             + " to "
14428                             + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
14429                             + "; replacing with new");
14430             pkgSetting = null;
14431         }
14432 
14433         String[] usesStaticLibraries = null;
14434         if (!parsedPackage.getUsesStaticLibraries().isEmpty()) {
14435             usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()];
14436             parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries);
14437         }
14438 
14439         final UUID newDomainSetId = injector.getDomainVerificationManagerInternal().generateNewId();
14440 
14441         // TODO(b/135203078): Remove appInfoFlag usage in favor of individually assigned booleans
14442         //  to avoid adding something that's unsupported due to lack of state, since it's called
14443         //  with null.
14444         final boolean createNewPackage = (pkgSetting == null);
14445         if (createNewPackage) {
14446             final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
14447             final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
14448 
14449             // Flags contain system values stored in the server variant of AndroidPackage,
14450             // and so the server-side PackageInfoUtils is still called, even without a
14451             // PackageSetting to pass in.
14452             int pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, null);
14453             int pkgPrivateFlags = PackageInfoUtils.appInfoPrivateFlags(parsedPackage, null);
14454 
14455             // REMOVE SharedUserSetting from method; update in a separate call
14456             pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),
14457                     originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting,
14458                     destCodeFile, parsedPackage.getNativeLibraryRootDir(),
14459                     AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage),
14460                     AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage),
14461                     parsedPackage.getVersionCode(), pkgFlags, pkgPrivateFlags, user,
14462                     true /*allowInstall*/, instantApp, virtualPreload,
14463                     UserManagerService.getInstance(), usesStaticLibraries,
14464                     parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(),
14465                     newDomainSetId);
14466         } else {
14467             // make a deep copy to avoid modifying any existing system state.
14468             pkgSetting = new PackageSetting(pkgSetting);
14469             pkgSetting.pkg = parsedPackage;
14470 
14471             // REMOVE SharedUserSetting from method; update in a separate call.
14472             //
14473             // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
14474             // secondaryCpuAbi are not known at this point so we always update them
14475             // to null here, only to reset them at a later point.
14476             Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
14477                     destCodeFile, parsedPackage.getNativeLibraryDir(),
14478                     AndroidPackageUtils.getPrimaryCpuAbi(parsedPackage, pkgSetting),
14479                     AndroidPackageUtils.getSecondaryCpuAbi(parsedPackage, pkgSetting),
14480                     PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
14481                     PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting),
14482                     UserManagerService.getInstance(),
14483                     usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
14484                     parsedPackage.getMimeGroups(), newDomainSetId);
14485         }
14486         if (createNewPackage && originalPkgSetting != null) {
14487             // This is the initial transition from the original package, so,
14488             // fix up the new package's name now. We must do this after looking
14489             // up the package under its new name, so getPackageLP takes care of
14490             // fiddling things correctly.
14491             parsedPackage.setPackageName(originalPkgSetting.name);
14492 
14493             // File a report about this.
14494             String msg = "New package " + pkgSetting.realName
14495                     + " renamed to replace old package " + pkgSetting.name;
14496             reportSettingsProblem(Log.WARN, msg);
14497         }
14498 
14499         final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
14500         // for existing packages, change the install state; but, only if it's explicitly specified
14501         if (!createNewPackage) {
14502             final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
14503             final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
14504             setInstantAppForUser(injector, pkgSetting, userId, instantApp, fullApp);
14505         }
14506         // TODO(patb): see if we can do away with disabled check here.
14507         if (disabledPkgSetting != null
14508                 || (0 != (scanFlags & SCAN_NEW_INSTALL)
14509                 && pkgSetting != null && pkgSetting.isSystem())) {
14510             pkgSetting.getPkgState().setUpdatedSystemApp(true);
14511         }
14512 
14513         parsedPackage
14514                 .setSeInfo(SELinuxMMAC.getSeInfo(parsedPackage, sharedUserSetting,
14515                         injector.getCompatibility()))
14516                 .setSeInfoUser(SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
14517                         userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId)));
14518 
14519         if (parsedPackage.isSystem()) {
14520             configurePackageComponents(parsedPackage);
14521         }
14522 
14523         final String cpuAbiOverride = deriveAbiOverride(request.cpuAbiOverride);
14524         final boolean isUpdatedSystemApp = pkgSetting.getPkgState().isUpdatedSystemApp();
14525 
14526         final File appLib32InstallDir = getAppLib32InstallDir();
14527         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
14528             if (needToDeriveAbi) {
14529                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
14530                 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
14531                         packageAbiHelper.derivePackageAbi(parsedPackage, isUpdatedSystemApp,
14532                                 cpuAbiOverride, appLib32InstallDir);
14533                 derivedAbi.first.applyTo(parsedPackage);
14534                 derivedAbi.second.applyTo(parsedPackage);
14535                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14536 
14537                 // Some system apps still use directory structure for native libraries
14538                 // in which case we might end up not detecting abi solely based on apk
14539                 // structure. Try to detect abi based on directory structure.
14540 
14541                 String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
14542                 if (parsedPackage.isSystem() && !isUpdatedSystemApp
14543                         && pkgRawPrimaryCpuAbi == null) {
14544                     final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
14545                             parsedPackage);
14546                     abis.applyTo(parsedPackage);
14547                     abis.applyTo(pkgSetting);
14548                     final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
14549                             packageAbiHelper.deriveNativeLibraryPaths(parsedPackage,
14550                                     isUpdatedSystemApp, appLib32InstallDir);
14551                     nativeLibraryPaths.applyTo(parsedPackage);
14552                 }
14553             } else {
14554                 // This is not a first boot or an upgrade, don't bother deriving the
14555                 // ABI during the scan. Instead, trust the value that was stored in the
14556                 // package setting.
14557                 parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings)
14558                         .setSecondaryCpuAbi(secondaryCpuAbiFromSettings);
14559 
14560                 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
14561                         packageAbiHelper.deriveNativeLibraryPaths(parsedPackage,
14562                                 isUpdatedSystemApp, appLib32InstallDir);
14563                 nativeLibraryPaths.applyTo(parsedPackage);
14564 
14565                 if (DEBUG_ABI_SELECTION) {
14566                     Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
14567                             parsedPackage.getPackageName() + " " +
14568                             AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage)
14569                             + ", "
14570                             + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage));
14571                 }
14572             }
14573         } else {
14574             if ((scanFlags & SCAN_MOVE) != 0) {
14575                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
14576                 // but we already have this packages package info in the PackageSetting. We just
14577                 // use that and derive the native library path based on the new codepath.
14578                 parsedPackage.setPrimaryCpuAbi(pkgSetting.primaryCpuAbiString)
14579                         .setSecondaryCpuAbi(pkgSetting.secondaryCpuAbiString);
14580             }
14581 
14582             // Set native library paths again. For moves, the path will be updated based on the
14583             // ABIs we've determined above. For non-moves, the path will be updated based on the
14584             // ABIs we determined during compilation, but the path will depend on the final
14585             // package path (after the rename away from the stage path).
14586             final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
14587                     packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isUpdatedSystemApp,
14588                             appLib32InstallDir);
14589             nativeLibraryPaths.applyTo(parsedPackage);
14590         }
14591 
14592         // This is a special case for the "system" package, where the ABI is
14593         // dictated by the zygote configuration (and init.rc). We should keep track
14594         // of this ABI so that we can deal with "normal" applications that run under
14595         // the same UID correctly.
14596         if (isPlatformPackage) {
14597             parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() ?
14598                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]);
14599         }
14600 
14601         // If there's a mismatch between the abi-override in the package setting
14602         // and the abiOverride specified for the install. Warn about this because we
14603         // would've already compiled the app without taking the package setting into
14604         // account.
14605         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
14606             if (cpuAbiOverride == null) {
14607                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
14608                         " for package " + parsedPackage.getPackageName());
14609             }
14610         }
14611 
14612         pkgSetting.primaryCpuAbiString = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
14613         pkgSetting.secondaryCpuAbiString = AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage);
14614         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
14615 
14616         if (DEBUG_ABI_SELECTION) {
14617             Slog.d(TAG, "Resolved nativeLibraryRoot for " + parsedPackage.getPackageName()
14618                     + " to root=" + parsedPackage.getNativeLibraryRootDir()
14619                     + ", to dir=" + parsedPackage.getNativeLibraryDir()
14620                     + ", isa=" + parsedPackage.isNativeLibraryRootRequiresIsa());
14621         }
14622 
14623         // Push the derived path down into PackageSettings so we know what to
14624         // clean up at uninstall time.
14625         pkgSetting.legacyNativeLibraryPathString = parsedPackage.getNativeLibraryRootDir();
14626 
14627         if (DEBUG_ABI_SELECTION) {
14628             Log.d(TAG, "Abis for package[" + parsedPackage.getPackageName() + "] are"
14629                     + " primary=" + pkgSetting.primaryCpuAbiString
14630                     + " secondary=" + pkgSetting.primaryCpuAbiString
14631                     + " abiOverride=" + pkgSetting.cpuAbiOverrideString);
14632         }
14633 
14634         if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
14635             // We don't do this here during boot because we can do it all
14636             // at once after scanning all existing packages.
14637             //
14638             // We also do this *before* we perform dexopt on this package, so that
14639             // we can avoid redundant dexopts, and also to make sure we've got the
14640             // code and package path correct.
14641             changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, parsedPackage,
14642                     packageAbiHelper.getAdjustedAbiForSharedUser(
14643                             pkgSetting.sharedUser.packages, parsedPackage));
14644         }
14645 
14646         parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions()
14647                 .contains(android.Manifest.permission.FACTORY_TEST));
14648 
14649         if (parsedPackage.isSystem()) {
14650             pkgSetting.setIsOrphaned(true);
14651         }
14652 
14653         // Take care of first install / last update times.
14654         final long scanFileTime = getLastModifiedTime(parsedPackage);
14655         if (currentTime != 0) {
14656             if (pkgSetting.firstInstallTime == 0) {
14657                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
14658             } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
14659                 pkgSetting.lastUpdateTime = currentTime;
14660             }
14661         } else if (pkgSetting.firstInstallTime == 0) {
14662             // We need *something*.  Take time time stamp of the file.
14663             pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
14664         } else if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0) {
14665             if (scanFileTime != pkgSetting.timeStamp) {
14666                 // A package on the system image has changed; consider this
14667                 // to be an update.
14668                 pkgSetting.lastUpdateTime = scanFileTime;
14669             }
14670         }
14671         pkgSetting.setTimeStamp(scanFileTime);
14672         // TODO(b/135203078): Remove, move to constructor
14673         pkgSetting.pkg = parsedPackage;
14674         pkgSetting.pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting);
14675         pkgSetting.pkgPrivateFlags =
14676                 PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting);
14677         if (parsedPackage.getLongVersionCode() != pkgSetting.versionCode) {
14678             pkgSetting.versionCode = parsedPackage.getLongVersionCode();
14679         }
14680         // Update volume if needed
14681         final String volumeUuid = parsedPackage.getVolumeUuid();
14682         if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
14683             Slog.i(PackageManagerService.TAG,
14684                     "Update" + (pkgSetting.isSystem() ? " system" : "")
14685                     + " package " + parsedPackage.getPackageName()
14686                     + " volume from " + pkgSetting.volumeUuid
14687                     + " to " + volumeUuid);
14688             pkgSetting.volumeUuid = volumeUuid;
14689         }
14690 
14691         SharedLibraryInfo staticSharedLibraryInfo = null;
14692         if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibName())) {
14693             staticSharedLibraryInfo =
14694                     AndroidPackageUtils.createSharedLibraryForStatic(parsedPackage);
14695         }
14696         List<SharedLibraryInfo> dynamicSharedLibraryInfos = null;
14697         if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) {
14698             dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size());
14699             for (String name : parsedPackage.getLibraryNames()) {
14700                 dynamicSharedLibraryInfos.add(
14701                         AndroidPackageUtils.createSharedLibraryForDynamic(parsedPackage, name));
14702             }
14703         }
14704 
14705         return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
14706                 !createNewPackage /* existingSettingCopied */, staticSharedLibraryInfo,
14707                 dynamicSharedLibraryInfos);
14708     }
14709 
14710     /**
14711      * Returns {@code true} if the given file contains code. Otherwise {@code false}.
14712      */
14713     private static boolean apkHasCode(String fileName) {
14714         StrictJarFile jarFile = null;
14715         try {
14716             jarFile = new StrictJarFile(fileName,
14717                     false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
14718             return jarFile.findEntry("classes.dex") != null;
14719         } catch (IOException ignore) {
14720         } finally {
14721             try {
14722                 if (jarFile != null) {
14723                     jarFile.close();
14724                 }
14725             } catch (IOException ignore) {}
14726         }
14727         return false;
14728     }
14729 
14730     /**
14731      * Enforces code policy for the package. This ensures that if an APK has
14732      * declared hasCode="true" in its manifest that the APK actually contains
14733      * code.
14734      *
14735      * @throws PackageManagerException If bytecode could not be found when it should exist
14736      */
14737     private static void assertCodePolicy(AndroidPackage pkg)
14738             throws PackageManagerException {
14739         final boolean shouldHaveCode = pkg.isHasCode();
14740         if (shouldHaveCode && !apkHasCode(pkg.getBaseApkPath())) {
14741             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
14742                     "Package " + pkg.getBaseApkPath() + " code is missing");
14743         }
14744 
14745         if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) {
14746             for (int i = 0; i < pkg.getSplitCodePaths().length; i++) {
14747                 final boolean splitShouldHaveCode =
14748                         (pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
14749                 if (splitShouldHaveCode && !apkHasCode(pkg.getSplitCodePaths()[i])) {
14750                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
14751                             "Package " + pkg.getSplitCodePaths()[i] + " code is missing");
14752                 }
14753             }
14754         }
14755     }
14756 
14757     /**
14758      * Applies policy to the parsed package based upon the given policy flags.
14759      * Ensures the package is in a good state.
14760      * <p>
14761      * Implementation detail: This method must NOT have any side effect. It would
14762      * ideally be static, but, it requires locks to read system state.
14763      */
14764     private static void applyPolicy(ParsedPackage parsedPackage, final @ParseFlags int parseFlags,
14765             final @ScanFlags int scanFlags, AndroidPackage platformPkg,
14766             boolean isUpdatedSystemApp) {
14767         if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
14768             parsedPackage.setSystem(true);
14769             // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
14770             //  is set during parse.
14771             if (parsedPackage.isDirectBootAware()) {
14772                 parsedPackage.setAllComponentsDirectBootAware(true);
14773             }
14774             if (compressedFileExists(parsedPackage.getPath())) {
14775                 parsedPackage.setStub(true);
14776             }
14777         } else {
14778             parsedPackage
14779                     // Non system apps cannot mark any broadcast as protected
14780                     .clearProtectedBroadcasts()
14781                     // non system apps can't be flagged as core
14782                     .setCoreApp(false)
14783                     // clear flags not applicable to regular apps
14784                     .setPersistent(false)
14785                     .setDefaultToDeviceProtectedStorage(false)
14786                     .setDirectBootAware(false)
14787                     // non system apps can't have permission priority
14788                     .capPermissionPriorities();
14789         }
14790         if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
14791             parsedPackage
14792                     .markNotActivitiesAsNotExportedIfSingleUser();
14793         }
14794 
14795         parsedPackage.setPrivileged((scanFlags & SCAN_AS_PRIVILEGED) != 0)
14796                 .setOem((scanFlags & SCAN_AS_OEM) != 0)
14797                 .setVendor((scanFlags & SCAN_AS_VENDOR) != 0)
14798                 .setProduct((scanFlags & SCAN_AS_PRODUCT) != 0)
14799                 .setSystemExt((scanFlags & SCAN_AS_SYSTEM_EXT) != 0)
14800                 .setOdm((scanFlags & SCAN_AS_ODM) != 0);
14801 
14802         // Check if the package is signed with the same key as the platform package.
14803         parsedPackage.setSignedWithPlatformKey(
14804                 (PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())
14805                         || (platformPkg != null && compareSignatures(
14806                         platformPkg.getSigningDetails().signatures,
14807                         parsedPackage.getSigningDetails().signatures
14808                 ) == PackageManager.SIGNATURE_MATCH))
14809         );
14810 
14811         if (!parsedPackage.isSystem()) {
14812             // Only system apps can use these features.
14813             parsedPackage.clearOriginalPackages()
14814                     .setRealPackage(null)
14815                     .clearAdoptPermissions();
14816         }
14817 
14818         PackageBackwardCompatibility.modifySharedLibraries(parsedPackage, isUpdatedSystemApp);
14819     }
14820 
14821     private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
14822             throws PackageManagerException {
14823         if (object == null) {
14824             throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
14825         }
14826         return object;
14827     }
14828 
14829     private <T extends ParsedMainComponent>
14830             void assertPackageProcesses(AndroidPackage pkg, List<T> components,
14831             Map<String, ParsedProcess> procs, String compName)
14832             throws PackageManagerException {
14833         if (components == null) {
14834             return;
14835         }
14836         for (int i = components.size() - 1; i >= 0; i--) {
14837             final ParsedMainComponent component = components.get(i);
14838             if (!procs.containsKey(component.getProcessName())) {
14839                 throw new PackageManagerException(
14840                         INSTALL_FAILED_PROCESS_NOT_DEFINED,
14841                         "Can't install because " + compName + " " + component.getClassName()
14842                                 + "'s process attribute " + component.getProcessName()
14843                                 + " (in package " + pkg.getPackageName()
14844                                 + ") is not included in the <processes> list");
14845             }
14846         }
14847     }
14848 
14849     /**
14850      * Asserts the parsed package is valid according to the given policy. If the
14851      * package is invalid, for whatever reason, throws {@link PackageManagerException}.
14852      * <p>
14853      * Implementation detail: This method must NOT have any side effects. It would
14854      * ideally be static, but, it requires locks to read system state.
14855      *
14856      * @throws PackageManagerException If the package fails any of the validation checks
14857      */
14858     private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags,
14859             final @ScanFlags int scanFlags)
14860                     throws PackageManagerException {
14861         if ((parseFlags & ParsingPackageUtils.PARSE_ENFORCE_CODE) != 0) {
14862             assertCodePolicy(pkg);
14863         }
14864 
14865         if (pkg.getPath() == null) {
14866             // Bail out. The resource and code paths haven't been set.
14867             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
14868                     "Code and resource paths haven't been set correctly");
14869         }
14870 
14871         // Check that there is an APEX package with the same name only during install/first boot
14872         // after OTA.
14873         final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0;
14874         final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
14875         if ((isUserInstall || isFirstBootOrUpgrade)
14876                 && mApexManager.isApexPackage(pkg.getPackageName())) {
14877             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
14878                     pkg.getPackageName()
14879                             + " is an APEX package and can't be installed as an APK.");
14880         }
14881 
14882         // Make sure we're not adding any bogus keyset info
14883         final KeySetManagerService ksms = mSettings.getKeySetManagerService();
14884         ksms.assertScannedPackageValid(pkg);
14885 
14886         synchronized (mLock) {
14887             // The special "android" package can only be defined once
14888             if (pkg.getPackageName().equals("android")) {
14889                 if (mAndroidApplication != null) {
14890                     Slog.w(TAG, "*************************************************");
14891                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
14892                     Slog.w(TAG, " codePath=" + pkg.getPath());
14893                     Slog.w(TAG, "*************************************************");
14894                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
14895                             "Core android package being redefined.  Skipping.");
14896                 }
14897             }
14898 
14899             // A package name must be unique; don't allow duplicates
14900             if ((scanFlags & SCAN_NEW_INSTALL) == 0
14901                     && mPackages.containsKey(pkg.getPackageName())) {
14902                 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
14903                         "Application package " + pkg.getPackageName()
14904                         + " already installed.  Skipping duplicate.");
14905             }
14906 
14907             if (pkg.isStaticSharedLibrary()) {
14908                 // Static libs have a synthetic package name containing the version
14909                 // but we still want the base name to be unique.
14910                 if ((scanFlags & SCAN_NEW_INSTALL) == 0
14911                         && mPackages.containsKey(pkg.getManifestPackageName())) {
14912                     throw new PackageManagerException(
14913                             "Duplicate static shared lib provider package");
14914                 }
14915 
14916                 // Static shared libraries should have at least O target SDK
14917                 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
14918                     throw new PackageManagerException(
14919                             "Packages declaring static-shared libs must target O SDK or higher");
14920                 }
14921 
14922                 // Package declaring static a shared lib cannot be instant apps
14923                 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
14924                     throw new PackageManagerException(
14925                             "Packages declaring static-shared libs cannot be instant apps");
14926                 }
14927 
14928                 // Package declaring static a shared lib cannot be renamed since the package
14929                 // name is synthetic and apps can't code around package manager internals.
14930                 if (!ArrayUtils.isEmpty(pkg.getOriginalPackages())) {
14931                     throw new PackageManagerException(
14932                             "Packages declaring static-shared libs cannot be renamed");
14933                 }
14934 
14935                 // Package declaring static a shared lib cannot declare dynamic libs
14936                 if (!ArrayUtils.isEmpty(pkg.getLibraryNames())) {
14937                     throw new PackageManagerException(
14938                             "Packages declaring static-shared libs cannot declare dynamic libs");
14939                 }
14940 
14941                 // Package declaring static a shared lib cannot declare shared users
14942                 if (pkg.getSharedUserId() != null) {
14943                     throw new PackageManagerException(
14944                             "Packages declaring static-shared libs cannot declare shared users");
14945                 }
14946 
14947                 // Static shared libs cannot declare activities
14948                 if (!pkg.getActivities().isEmpty()) {
14949                     throw new PackageManagerException(
14950                             "Static shared libs cannot declare activities");
14951                 }
14952 
14953                 // Static shared libs cannot declare services
14954                 if (!pkg.getServices().isEmpty()) {
14955                     throw new PackageManagerException(
14956                             "Static shared libs cannot declare services");
14957                 }
14958 
14959                 // Static shared libs cannot declare providers
14960                 if (!pkg.getProviders().isEmpty()) {
14961                     throw new PackageManagerException(
14962                             "Static shared libs cannot declare content providers");
14963                 }
14964 
14965                 // Static shared libs cannot declare receivers
14966                 if (!pkg.getReceivers().isEmpty()) {
14967                     throw new PackageManagerException(
14968                             "Static shared libs cannot declare broadcast receivers");
14969                 }
14970 
14971                 // Static shared libs cannot declare permission groups
14972                 if (!pkg.getPermissionGroups().isEmpty()) {
14973                     throw new PackageManagerException(
14974                             "Static shared libs cannot declare permission groups");
14975                 }
14976 
14977                 // Static shared libs cannot declare attributions
14978                 if (!pkg.getAttributions().isEmpty()) {
14979                     throw new PackageManagerException(
14980                             "Static shared libs cannot declare features");
14981                 }
14982 
14983                 // Static shared libs cannot declare permissions
14984                 if (!pkg.getPermissions().isEmpty()) {
14985                     throw new PackageManagerException(
14986                             "Static shared libs cannot declare permissions");
14987                 }
14988 
14989                 // Static shared libs cannot declare protected broadcasts
14990                 if (!pkg.getProtectedBroadcasts().isEmpty()) {
14991                     throw new PackageManagerException(
14992                             "Static shared libs cannot declare protected broadcasts");
14993                 }
14994 
14995                 // Static shared libs cannot be overlay targets
14996                 if (pkg.getOverlayTarget() != null) {
14997                     throw new PackageManagerException(
14998                             "Static shared libs cannot be overlay targets");
14999                 }
15000 
15001                 // The version codes must be ordered as lib versions
15002                 long minVersionCode = Long.MIN_VALUE;
15003                 long maxVersionCode = Long.MAX_VALUE;
15004 
15005                 WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
15006                         pkg.getStaticSharedLibName());
15007                 if (versionedLib != null) {
15008                     final int versionCount = versionedLib.size();
15009                     for (int i = 0; i < versionCount; i++) {
15010                         SharedLibraryInfo libInfo = versionedLib.valueAt(i);
15011                         final long libVersionCode = libInfo.getDeclaringPackage()
15012                                 .getLongVersionCode();
15013                         if (libInfo.getLongVersion() < pkg.getStaticSharedLibVersion()) {
15014                             minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
15015                         } else if (libInfo.getLongVersion()
15016                                 > pkg.getStaticSharedLibVersion()) {
15017                             maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
15018                         } else {
15019                             minVersionCode = maxVersionCode = libVersionCode;
15020                             break;
15021                         }
15022                     }
15023                 }
15024                 if (pkg.getLongVersionCode() < minVersionCode
15025                         || pkg.getLongVersionCode() > maxVersionCode) {
15026                     throw new PackageManagerException("Static shared"
15027                             + " lib version codes must be ordered as lib versions");
15028                 }
15029             }
15030 
15031             // If we're only installing presumed-existing packages, require that the
15032             // scanned APK is both already known and at the path previously established
15033             // for it.  Previously unknown packages we pick up normally, but if we have an
15034             // a priori expectation about this package's install presence, enforce it.
15035             // With a singular exception for new system packages. When an OTA contains
15036             // a new system package, we allow the codepath to change from a system location
15037             // to the user-installed location. If we don't allow this change, any newer,
15038             // user-installed version of the application will be ignored.
15039             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
15040                 if (mExpectingBetter.containsKey(pkg.getPackageName())) {
15041                     Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package "
15042                             + pkg.getPackageName());
15043                 } else {
15044                     PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());
15045                     if (known != null) {
15046                         if (DEBUG_PACKAGE_SCANNING) {
15047                             Log.d(TAG, "Examining " + pkg.getPath()
15048                                     + " and requiring known path " + known.getPathString());
15049                         }
15050                         if (!pkg.getPath().equals(known.getPathString())) {
15051                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
15052                                     "Application package " + pkg.getPackageName()
15053                                     + " found at " + pkg.getPath()
15054                                     + " but expected at " + known.getPathString()
15055                                     + "; ignoring.");
15056                         }
15057                     } else {
15058                         throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
15059                                 "Application package " + pkg.getPackageName()
15060                                 + " not found; ignoring.");
15061                     }
15062                 }
15063             }
15064 
15065             // Verify that this new package doesn't have any content providers
15066             // that conflict with existing packages.  Only do this if the
15067             // package isn't already installed, since we don't want to break
15068             // things that are installed.
15069             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
15070                 mComponentResolver.assertProvidersNotDefined(pkg);
15071             }
15072 
15073             // If this package has defined explicit processes, then ensure that these are
15074             // the only processes used by its components.
15075             final Map<String, ParsedProcess> procs = pkg.getProcesses();
15076             if (!procs.isEmpty()) {
15077                 if (!procs.containsKey(pkg.getProcessName())) {
15078                     throw new PackageManagerException(
15079                             INSTALL_FAILED_PROCESS_NOT_DEFINED,
15080                             "Can't install because application tag's process attribute "
15081                                     + pkg.getProcessName()
15082                                     + " (in package " + pkg.getPackageName()
15083                                     + ") is not included in the <processes> list");
15084                 }
15085                 assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity");
15086                 assertPackageProcesses(pkg, pkg.getServices(), procs, "service");
15087                 assertPackageProcesses(pkg, pkg.getReceivers(), procs, "receiver");
15088                 assertPackageProcesses(pkg, pkg.getProviders(), procs, "provider");
15089             }
15090 
15091             // Verify that packages sharing a user with a privileged app are marked as privileged.
15092             if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
15093                 SharedUserSetting sharedUserSetting = null;
15094                 try {
15095                     sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(),
15096                             0, 0, false);
15097                 } catch (PackageManagerException ignore) {
15098                 }
15099                 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
15100                     // Exempt SharedUsers signed with the platform key.
15101                     PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
15102                     if (!comparePackageSignatures(platformPkgSetting,
15103                             pkg.getSigningDetails().signatures)) {
15104                         throw new PackageManagerException("Apps that share a user with a " +
15105                                 "privileged app must themselves be marked as privileged. " +
15106                                 pkg.getPackageName() + " shares privileged user " +
15107                                 pkg.getSharedUserId() + ".");
15108                     }
15109                 }
15110             }
15111 
15112             // Apply policies specific for runtime resource overlays (RROs).
15113             if (pkg.getOverlayTarget() != null) {
15114                 // System overlays have some restrictions on their use of the 'static' state.
15115                 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
15116                     // We are scanning a system overlay. This can be the first scan of the
15117                     // system/vendor/oem partition, or an update to the system overlay.
15118                     if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) {
15119                         // This must be an update to a system overlay. Immutable overlays cannot be
15120                         // upgraded.
15121                         Objects.requireNonNull(mOverlayConfig,
15122                                 "Parsing non-system dir before overlay configs are initialized");
15123                         if (!mOverlayConfig.isMutable(pkg.getPackageName())) {
15124                             throw new PackageManagerException("Overlay "
15125                                     + pkg.getPackageName()
15126                                     + " is static and cannot be upgraded.");
15127                         }
15128                     } else {
15129                         if ((scanFlags & SCAN_AS_VENDOR) != 0) {
15130                             if (pkg.getTargetSdkVersion() < getVendorPartitionVersion()) {
15131                                 Slog.w(TAG, "System overlay " + pkg.getPackageName()
15132                                         + " targets an SDK below the required SDK level of vendor"
15133                                         + " overlays (" + getVendorPartitionVersion() + ")."
15134                                         + " This will become an install error in a future release");
15135                             }
15136                         } else if (pkg.getTargetSdkVersion() < Build.VERSION.SDK_INT) {
15137                             Slog.w(TAG, "System overlay " + pkg.getPackageName()
15138                                     + " targets an SDK below the required SDK level of system"
15139                                     + " overlays (" + Build.VERSION.SDK_INT + ")."
15140                                     + " This will become an install error in a future release");
15141                         }
15142                     }
15143                 } else {
15144                     // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
15145                     // signed with the platform certificate. Check this in increasing order of
15146                     // computational cost.
15147                     if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
15148                         final PackageSetting platformPkgSetting =
15149                                 mSettings.getPackageLPr("android");
15150                         if (!comparePackageSignatures(platformPkgSetting,
15151                                 pkg.getSigningDetails().signatures)) {
15152                             throw new PackageManagerException("Overlay "
15153                                     + pkg.getPackageName()
15154                                     + " must target Q or later, "
15155                                     + "or be signed with the platform certificate");
15156                         }
15157                     }
15158 
15159                     // A non-preloaded overlay package, without <overlay android:targetName>, will
15160                     // only be used if it is signed with the same certificate as its target OR if
15161                     // it is signed with the same certificate as a reference package declared
15162                     // in 'overlay-config-signature' tag of SystemConfig.
15163                     // If the target is already installed or 'overlay-config-signature' tag in
15164                     // SystemConfig is set, check this here to augment the last line of defense
15165                     // which is OMS.
15166                     if (pkg.getOverlayTargetName() == null) {
15167                         final PackageSetting targetPkgSetting =
15168                                 mSettings.getPackageLPr(pkg.getOverlayTarget());
15169                         if (targetPkgSetting != null) {
15170                             if (!comparePackageSignatures(targetPkgSetting,
15171                                     pkg.getSigningDetails().signatures)) {
15172                                 // check reference signature
15173                                 if (mOverlayConfigSignaturePackage == null) {
15174                                     throw new PackageManagerException("Overlay "
15175                                             + pkg.getPackageName() + " and target "
15176                                             + pkg.getOverlayTarget() + " signed with"
15177                                             + " different certificates, and the overlay lacks"
15178                                             + " <overlay android:targetName>");
15179                                 }
15180                                 final PackageSetting refPkgSetting =
15181                                         mSettings.getPackageLPr(mOverlayConfigSignaturePackage);
15182                                 if (!comparePackageSignatures(refPkgSetting,
15183                                         pkg.getSigningDetails().signatures)) {
15184                                     throw new PackageManagerException("Overlay "
15185                                             + pkg.getPackageName() + " signed with a different "
15186                                             + "certificate than both the reference package and "
15187                                             + "target " + pkg.getOverlayTarget() + ", and the "
15188                                             + "overlay lacks <overlay android:targetName>");
15189                                 }
15190                             }
15191                         }
15192                     }
15193                 }
15194             }
15195 
15196             // If the package is not on a system partition ensure it is signed with at least the
15197             // minimum signature scheme version required for its target SDK.
15198             if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) {
15199                 int minSignatureSchemeVersion =
15200                         ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
15201                                 pkg.getTargetSdkVersion());
15202                 if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) {
15203                     throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
15204                             "No signature found in package of version " + minSignatureSchemeVersion
15205                                     + " or newer for package " + pkg.getPackageName());
15206                 }
15207             }
15208         }
15209     }
15210 
15211     @GuardedBy("mLock")
15212     private boolean addBuiltInSharedLibraryLocked(SystemConfig.SharedLibraryEntry entry) {
15213         if (nonStaticSharedLibExistsLocked(entry.name)) {
15214             return false;
15215         }
15216 
15217         SharedLibraryInfo libraryInfo = new SharedLibraryInfo(entry.filename, null, null,
15218                 entry.name, (long) SharedLibraryInfo.VERSION_UNDEFINED,
15219                 SharedLibraryInfo.TYPE_BUILTIN,
15220                 new VersionedPackage(PLATFORM_PACKAGE_NAME, (long)0), null, null,
15221                 entry.isNative);
15222 
15223         commitSharedLibraryInfoLocked(libraryInfo);
15224         return true;
15225     }
15226 
15227     @GuardedBy("mLock")
15228     private boolean nonStaticSharedLibExistsLocked(String name) {
15229         return sharedLibExists(name, SharedLibraryInfo.VERSION_UNDEFINED, mSharedLibraries);
15230     }
15231 
15232     private static boolean sharedLibExists(final String name, final long version,
15233             Map<String, WatchedLongSparseArray<SharedLibraryInfo>> librarySource) {
15234         WatchedLongSparseArray<SharedLibraryInfo> versionedLib = librarySource.get(name);
15235         if (versionedLib != null && versionedLib.indexOfKey(version) >= 0) {
15236             return true;
15237         }
15238         return false;
15239     }
15240 
15241     @GuardedBy("mLock")
15242     private void commitSharedLibraryInfoLocked(SharedLibraryInfo libraryInfo) {
15243         final String name = libraryInfo.getName();
15244         WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
15245         if (versionedLib == null) {
15246             versionedLib = new WatchedLongSparseArray<>();
15247             mSharedLibraries.put(name, versionedLib);
15248         }
15249         final String declaringPackageName = libraryInfo.getDeclaringPackage().getPackageName();
15250         if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
15251             mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
15252         }
15253         versionedLib.put(libraryInfo.getLongVersion(), libraryInfo);
15254     }
15255 
15256     private boolean removeSharedLibraryLPw(String name, long version) {
15257         WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
15258         if (versionedLib == null) {
15259             return false;
15260         }
15261         final int libIdx = versionedLib.indexOfKey(version);
15262         if (libIdx < 0) {
15263             return false;
15264         }
15265         SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
15266 
15267         // Remove the shared library overlays from its dependent packages.
15268         for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
15269             final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
15270                     libraryInfo, 0, Process.SYSTEM_UID, currentUserId);
15271             if (dependents == null) {
15272                 continue;
15273             }
15274             for (VersionedPackage dependentPackage : dependents) {
15275                 final PackageSetting ps = mSettings.getPackageLPr(
15276                         dependentPackage.getPackageName());
15277                 if (ps != null) {
15278                     ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
15279                 }
15280             }
15281         }
15282 
15283         versionedLib.remove(version);
15284         if (versionedLib.size() <= 0) {
15285             mSharedLibraries.remove(name);
15286             if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
15287                 mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
15288                         .getPackageName());
15289             }
15290         }
15291         return true;
15292     }
15293 
15294     @Override
15295     public Property getProperty(String propertyName, String packageName, String className) {
15296         Objects.requireNonNull(propertyName);
15297         Objects.requireNonNull(packageName);
15298         synchronized (mLock) {
15299             final PackageSetting ps = getPackageSetting(packageName);
15300             if (shouldFilterApplicationLocked(ps, Binder.getCallingUid(),
15301                     UserHandle.getCallingUserId())) {
15302                 return null;
15303             }
15304             return mPackageProperty.getProperty(propertyName, packageName, className);
15305         }
15306     }
15307 
15308     @Override
15309     public ParceledListSlice<Property> queryProperty(
15310             String propertyName, @PropertyLocation int componentType) {
15311         Objects.requireNonNull(propertyName);
15312         final int callingUid = Binder.getCallingUid();
15313         final int callingUserId = UserHandle.getCallingUserId();
15314         final List<Property> result =
15315                 mPackageProperty.queryProperty(propertyName, componentType, packageName -> {
15316                     final PackageSetting ps = getPackageSetting(packageName);
15317                     return shouldFilterApplicationLocked(ps, callingUid, callingUserId);
15318                 });
15319         if (result == null) {
15320             return ParceledListSlice.emptyList();
15321         }
15322         return new ParceledListSlice<>(result);
15323     }
15324 
15325     /**
15326      * Adds a scanned package to the system. When this method is finished, the package will
15327      * be available for query, resolution, etc...
15328      */
15329     private void commitPackageSettings(@NonNull AndroidPackage pkg, @Nullable AndroidPackage oldPkg,
15330             @NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting,
15331             final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
15332         final String pkgName = pkg.getPackageName();
15333         if (mCustomResolverComponentName != null &&
15334                 mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) {
15335             setUpCustomResolverActivity(pkg, pkgSetting);
15336         }
15337 
15338         if (pkg.getPackageName().equals("android")) {
15339             synchronized (mLock) {
15340                 // Set up information for our fall-back user intent resolution activity.
15341                 mPlatformPackage = pkg;
15342 
15343                 // The instance stored in PackageManagerService is special cased to be non-user
15344                 // specific, so initialize all the needed fields here.
15345                 mAndroidApplication = pkg.toAppInfoWithoutState();
15346                 mAndroidApplication.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
15347                 mAndroidApplication.privateFlags =
15348                         PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
15349                 mAndroidApplication.initForUser(UserHandle.USER_SYSTEM);
15350 
15351                 if (!mResolverReplaced) {
15352                     mResolveActivity.applicationInfo = mAndroidApplication;
15353                     mResolveActivity.name = ResolverActivity.class.getName();
15354                     mResolveActivity.packageName = mAndroidApplication.packageName;
15355                     mResolveActivity.processName = "system:ui";
15356                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
15357                     mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
15358                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
15359                             | ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
15360                     mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
15361                     mResolveActivity.exported = true;
15362                     mResolveActivity.enabled = true;
15363                     mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
15364                     mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
15365                             | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
15366                             | ActivityInfo.CONFIG_SCREEN_LAYOUT
15367                             | ActivityInfo.CONFIG_ORIENTATION
15368                             | ActivityInfo.CONFIG_KEYBOARD
15369                             | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
15370                     mResolveInfo.activityInfo = mResolveActivity;
15371                     mResolveInfo.priority = 0;
15372                     mResolveInfo.preferredOrder = 0;
15373                     mResolveInfo.match = 0;
15374                     mResolveComponentName = new ComponentName(
15375                             mAndroidApplication.packageName, mResolveActivity.name);
15376                 }
15377                 onChanged();
15378             }
15379         }
15380 
15381         ArrayList<AndroidPackage> clientLibPkgs = null;
15382         // writer
15383         synchronized (mLock) {
15384             if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) {
15385                 for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
15386                     commitSharedLibraryInfoLocked(info);
15387                 }
15388                 final Map<String, AndroidPackage> combinedSigningDetails =
15389                         reconciledPkg.getCombinedAvailablePackages();
15390                 try {
15391                     // Shared libraries for the package need to be updated.
15392                     updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
15393                             combinedSigningDetails);
15394                 } catch (PackageManagerException e) {
15395                     Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
15396                 }
15397                 // Update all applications that use this library. Skip when booting
15398                 // since this will be done after all packages are scaned.
15399                 if ((scanFlags & SCAN_BOOTING) == 0) {
15400                     clientLibPkgs = updateAllSharedLibrariesLocked(pkg, pkgSetting,
15401                             combinedSigningDetails);
15402                 }
15403             }
15404         }
15405         if (reconciledPkg.installResult != null) {
15406             reconciledPkg.installResult.libraryConsumers = clientLibPkgs;
15407         }
15408 
15409         if ((scanFlags & SCAN_BOOTING) != 0) {
15410             // No apps can run during boot scan, so they don't need to be frozen
15411         } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
15412             // Caller asked to not kill app, so it's probably not frozen
15413         } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
15414             // Caller asked us to ignore frozen check for some reason; they
15415             // probably didn't know the package name
15416         } else {
15417             // We're doing major surgery on this package, so it better be frozen
15418             // right now to keep it from launching
15419             checkPackageFrozen(pkgName);
15420         }
15421 
15422         // Also need to kill any apps that are dependent on the library.
15423         if (clientLibPkgs != null) {
15424             for (int i=0; i<clientLibPkgs.size(); i++) {
15425                 AndroidPackage clientPkg = clientLibPkgs.get(i);
15426                 killApplication(clientPkg.getPackageName(),
15427                         clientPkg.getUid(), "update lib");
15428             }
15429         }
15430 
15431         // writer
15432         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
15433 
15434         synchronized (mLock) {
15435             // We don't expect installation to fail beyond this point
15436             // Add the new setting to mSettings
15437             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
15438             // Add the new setting to mPackages
15439             mPackages.put(pkg.getPackageName(), pkg);
15440             if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
15441                 mApexManager.registerApkInApex(pkg);
15442             }
15443 
15444             // Add the package's KeySets to the global KeySetManagerService
15445             KeySetManagerService ksms = mSettings.getKeySetManagerService();
15446             ksms.addScannedPackageLPw(pkg);
15447 
15448             mComponentResolver.addAllComponents(pkg, chatty);
15449             final boolean isReplace =
15450                     reconciledPkg.prepareResult != null && reconciledPkg.prepareResult.replace;
15451             mAppsFilter.addPackage(pkgSetting, isReplace);
15452             mPackageProperty.addAllProperties(pkg);
15453 
15454             if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) {
15455                 mDomainVerificationManager.addPackage(pkgSetting);
15456             } else {
15457                 mDomainVerificationManager.migrateState(oldPkgSetting, pkgSetting);
15458             }
15459 
15460             int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
15461             StringBuilder r = null;
15462             int i;
15463             for (i = 0; i < collectionSize; i++) {
15464                 ParsedInstrumentation a = pkg.getInstrumentations().get(i);
15465                 a.setPackageName(pkg.getPackageName());
15466                 mInstrumentation.put(a.getComponentName(), a);
15467                 if (chatty) {
15468                     if (r == null) {
15469                         r = new StringBuilder(256);
15470                     } else {
15471                         r.append(' ');
15472                     }
15473                     r.append(a.getName());
15474                 }
15475             }
15476             if (r != null) {
15477                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
15478             }
15479 
15480             final List<String> protectedBroadcasts = pkg.getProtectedBroadcasts();
15481             if (!protectedBroadcasts.isEmpty()) {
15482                 synchronized (mProtectedBroadcasts) {
15483                     mProtectedBroadcasts.addAll(protectedBroadcasts);
15484                 }
15485             }
15486 
15487             mPermissionManager.onPackageAdded(pkg, (scanFlags & SCAN_AS_INSTANT_APP) != 0, oldPkg);
15488         }
15489 
15490         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15491     }
15492 
15493     private void setUpCustomResolverActivity(AndroidPackage pkg, PackageSetting pkgSetting) {
15494         synchronized (mLock) {
15495             mResolverReplaced = true;
15496 
15497             // The instance created in PackageManagerService is special cased to be non-user
15498             // specific, so initialize all the needed fields here.
15499             ApplicationInfo appInfo = pkg.toAppInfoWithoutState();
15500             appInfo.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
15501             appInfo.privateFlags =
15502                     PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
15503             appInfo.initForUser(UserHandle.USER_SYSTEM);
15504 
15505             // Set up information for custom user intent resolution activity.
15506             mResolveActivity.applicationInfo = appInfo;
15507             mResolveActivity.name = mCustomResolverComponentName.getClassName();
15508             mResolveActivity.packageName = pkg.getPackageName();
15509             mResolveActivity.processName = pkg.getProcessName();
15510             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
15511             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
15512                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
15513             mResolveActivity.theme = 0;
15514             mResolveActivity.exported = true;
15515             mResolveActivity.enabled = true;
15516             mResolveInfo.activityInfo = mResolveActivity;
15517             mResolveInfo.priority = 0;
15518             mResolveInfo.preferredOrder = 0;
15519             mResolveInfo.match = 0;
15520             mResolveComponentName = mCustomResolverComponentName;
15521             onChanged();
15522             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
15523                     mResolveComponentName);
15524         }
15525     }
15526 
15527     private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
15528         if (installerActivity == null) {
15529             if (DEBUG_INSTANT) {
15530                 Slog.d(TAG, "Clear ephemeral installer activity");
15531             }
15532             mInstantAppInstallerActivity = null;
15533             onChanged();
15534             return;
15535         }
15536 
15537         if (DEBUG_INSTANT) {
15538             Slog.d(TAG, "Set ephemeral installer activity: "
15539                     + installerActivity.getComponentName());
15540         }
15541         // Set up information for ephemeral installer activity
15542         mInstantAppInstallerActivity = installerActivity;
15543         mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
15544                 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
15545         mInstantAppInstallerActivity.exported = true;
15546         mInstantAppInstallerActivity.enabled = true;
15547         mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
15548         mInstantAppInstallerInfo.priority = 1;
15549         mInstantAppInstallerInfo.preferredOrder = 1;
15550         mInstantAppInstallerInfo.isDefault = true;
15551         mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
15552                 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
15553         onChanged();
15554     }
15555 
15556     private void killApplication(String pkgName, @AppIdInt int appId, String reason) {
15557         killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
15558     }
15559 
15560     private void killApplication(String pkgName, @AppIdInt int appId,
15561             @UserIdInt int userId, String reason) {
15562         // Request the ActivityManager to kill the process(only for existing packages)
15563         // so that we do not end up in a confused state while the user is still using the older
15564         // version of the application while the new one gets installed.
15565         final long token = Binder.clearCallingIdentity();
15566         try {
15567             IActivityManager am = ActivityManager.getService();
15568             if (am != null) {
15569                 try {
15570                     am.killApplication(pkgName, appId, userId, reason);
15571                 } catch (RemoteException e) {
15572                 }
15573             }
15574         } finally {
15575             Binder.restoreCallingIdentity(token);
15576         }
15577     }
15578 
15579     private void removePackageLI(AndroidPackage pkg, boolean chatty) {
15580         // Remove the parent package setting
15581         PackageSetting ps = getPackageSetting(pkg.getPackageName());
15582         if (ps != null) {
15583             removePackageLI(ps.name, chatty);
15584         } else if (DEBUG_REMOVE && chatty) {
15585             Log.d(TAG, "Not removing package " + pkg.getPackageName() + "; mExtras == null");
15586         }
15587     }
15588 
15589     private void removePackageLI(String packageName, boolean chatty) {
15590         if (DEBUG_INSTALL) {
15591             if (chatty)
15592                 Log.d(TAG, "Removing package " + packageName);
15593         }
15594 
15595         // writer
15596         synchronized (mLock) {
15597             final AndroidPackage removedPackage = mPackages.remove(packageName);
15598             if (removedPackage != null) {
15599                 cleanPackageDataStructuresLILPw(removedPackage, chatty);
15600             }
15601         }
15602     }
15603 
15604     private void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
15605         mComponentResolver.removeAllComponents(pkg, chatty);
15606         mPermissionManager.onPackageRemoved(pkg);
15607         mPackageProperty.removeAllProperties(pkg);
15608 
15609         final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations());
15610         StringBuilder r = null;
15611         int i;
15612         for (i = 0; i < instrumentationSize; i++) {
15613             ParsedInstrumentation a = pkg.getInstrumentations().get(i);
15614             mInstrumentation.remove(a.getComponentName());
15615             if (DEBUG_REMOVE && chatty) {
15616                 if (r == null) {
15617                     r = new StringBuilder(256);
15618                 } else {
15619                     r.append(' ');
15620                 }
15621                 r.append(a.getName());
15622             }
15623         }
15624         if (r != null) {
15625             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
15626         }
15627 
15628         r = null;
15629         if (pkg.isSystem()) {
15630             // Only system apps can hold shared libraries.
15631             final int libraryNamesSize = pkg.getLibraryNames().size();
15632             for (i = 0; i < libraryNamesSize; i++) {
15633                 String name = pkg.getLibraryNames().get(i);
15634                 if (removeSharedLibraryLPw(name, 0)) {
15635                     if (DEBUG_REMOVE && chatty) {
15636                         if (r == null) {
15637                             r = new StringBuilder(256);
15638                         } else {
15639                             r.append(' ');
15640                         }
15641                         r.append(name);
15642                     }
15643                 }
15644             }
15645         }
15646 
15647         r = null;
15648 
15649         // Any package can hold static shared libraries.
15650         if (pkg.getStaticSharedLibName() != null) {
15651             if (removeSharedLibraryLPw(pkg.getStaticSharedLibName(),
15652                     pkg.getStaticSharedLibVersion())) {
15653                 if (DEBUG_REMOVE && chatty) {
15654                     if (r == null) {
15655                         r = new StringBuilder(256);
15656                     } else {
15657                         r.append(' ');
15658                     }
15659                     r.append(pkg.getStaticSharedLibName());
15660                 }
15661             }
15662         }
15663 
15664         if (r != null) {
15665             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
15666         }
15667     }
15668 
15669     @Override
15670     public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
15671             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
15672             final int[] userIds, int[] instantUserIds,
15673             @Nullable SparseArray<int[]> broadcastAllowList,
15674             @Nullable Bundle bOptions) {
15675         mHandler.post(() -> {
15676             try {
15677                 final IActivityManager am = ActivityManager.getService();
15678                 if (am == null) return;
15679                 final int[] resolvedUserIds;
15680                 if (userIds == null) {
15681                     resolvedUserIds = am.getRunningUserIds();
15682                 } else {
15683                     resolvedUserIds = userIds;
15684                 }
15685                 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
15686                         resolvedUserIds, false, broadcastAllowList, bOptions);
15687                 if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
15688                     doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
15689                             instantUserIds, true, null, bOptions);
15690                 }
15691             } catch (RemoteException ex) {
15692             }
15693         });
15694     }
15695 
15696     @Override
15697     public void notifyPackageAdded(String packageName, int uid) {
15698         final PackageListObserver[] observers;
15699         synchronized (mLock) {
15700             if (mPackageListObservers.size() == 0) {
15701                 return;
15702             }
15703             final PackageListObserver[] observerArray =
15704                     new PackageListObserver[mPackageListObservers.size()];
15705             observers = mPackageListObservers.toArray(observerArray);
15706         }
15707         for (int i = observers.length - 1; i >= 0; --i) {
15708             observers[i].onPackageAdded(packageName, uid);
15709         }
15710     }
15711 
15712     @Override
15713     public void notifyPackageChanged(String packageName, int uid) {
15714         final PackageListObserver[] observers;
15715         synchronized (mLock) {
15716             if (mPackageListObservers.size() == 0) {
15717                 return;
15718             }
15719             final PackageListObserver[] observerArray =
15720                     new PackageListObserver[mPackageListObservers.size()];
15721             observers = mPackageListObservers.toArray(observerArray);
15722         }
15723         for (int i = observers.length - 1; i >= 0; --i) {
15724             observers[i].onPackageChanged(packageName, uid);
15725         }
15726     }
15727 
15728     private static final Comparator<ProviderInfo> sProviderInitOrderSorter = (p1, p2) -> {
15729         final int v1 = p1.initOrder;
15730         final int v2 = p2.initOrder;
15731         return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
15732     };
15733 
15734     @Override
notifyPackageRemoved(String packageName, int uid)15735     public void notifyPackageRemoved(String packageName, int uid) {
15736         final PackageListObserver[] observers;
15737         synchronized (mLock) {
15738             if (mPackageListObservers.size() == 0) {
15739                 return;
15740             }
15741             final PackageListObserver[] observerArray =
15742                     new PackageListObserver[mPackageListObservers.size()];
15743             observers = mPackageListObservers.toArray(observerArray);
15744         }
15745         for (int i = observers.length - 1; i >= 0; --i) {
15746             observers[i].onPackageRemoved(packageName, uid);
15747         }
15748     }
15749 
15750     /**
15751      * Sends a broadcast for the given action.
15752      * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
15753      * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
15754      * the system and applications allowed to see instant applications to receive package
15755      * lifecycle events for instant applications.
15756      */
doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras, int flags, String targetPkg, IIntentReceiver finishedReceiver, int[] userIds, boolean isInstantApp, @Nullable SparseArray<int[]> broadcastAllowList, @Nullable Bundle bOptions)15757     private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
15758             int flags, String targetPkg, IIntentReceiver finishedReceiver,
15759             int[] userIds, boolean isInstantApp, @Nullable SparseArray<int[]> broadcastAllowList,
15760             @Nullable Bundle bOptions) {
15761         for (int id : userIds) {
15762             final Intent intent = new Intent(action,
15763                     pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
15764             final String[] requiredPermissions =
15765                     isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
15766             if (extras != null) {
15767                 intent.putExtras(extras);
15768             }
15769             if (targetPkg != null) {
15770                 intent.setPackage(targetPkg);
15771             }
15772             // Modify the UID when posting to other users
15773             int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
15774             if (uid > 0 && UserHandle.getUserId(uid) != id) {
15775                 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
15776                 intent.putExtra(Intent.EXTRA_UID, uid);
15777             }
15778             if (broadcastAllowList != null && PLATFORM_PACKAGE_NAME.equals(targetPkg)) {
15779                 intent.putExtra(Intent.EXTRA_VISIBILITY_ALLOW_LIST, broadcastAllowList.get(id));
15780             }
15781             intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
15782             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
15783             if (DEBUG_BROADCASTS) {
15784                 RuntimeException here = new RuntimeException("here");
15785                 here.fillInStackTrace();
15786                 Slog.d(TAG, "Sending to user " + id + ": "
15787                         + intent.toShortString(false, true, false, false)
15788                         + " " + intent.getExtras(), here);
15789             }
15790             mInjector.getLocalService(ActivityManagerInternal.class).broadcastIntent(
15791                     intent, finishedReceiver, requiredPermissions,
15792                     finishedReceiver != null, id,
15793                     broadcastAllowList == null ? null : broadcastAllowList.get(id),
15794                     bOptions);
15795         }
15796     }
15797 
15798     /**
15799      * Check if the external storage media is available. This is true if there
15800      * is a mounted external storage medium or if the external storage is
15801      * emulated.
15802      */
isExternalMediaAvailable()15803     private boolean isExternalMediaAvailable() {
15804         return mMediaMounted || Environment.isExternalStorageEmulated();
15805     }
15806 
15807     /**
15808      * Ensure that the install reason matches what we know about the package installer (e.g. whether
15809      * it is acting on behalf on an enterprise or the user).
15810      *
15811      * Note that the ordering of the conditionals in this method is important. The checks we perform
15812      * are as follows, in this order:
15813      *
15814      * 1) If the install is being performed by a system app, we can trust the app to have set the
15815      *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
15816      *    what it is.
15817      * 2) If the install is being performed by a device or profile owner app, the install reason
15818      *    should be enterprise policy. However, we cannot be sure that the device or profile owner
15819      *    set the install reason correctly. If the app targets an older SDK version where install
15820      *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
15821      *    unset or wrong. Thus, we force the install reason to be enterprise policy.
15822      * 3) In all other cases, the install is being performed by a regular app that is neither part
15823      *    of the system nor a device or profile owner. We have no reason to believe that this app is
15824      *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
15825      *    set to enterprise policy and if so, change it to unknown instead.
15826      */
fixUpInstallReason(String installerPackageName, int installerUid, int installReason)15827     private int fixUpInstallReason(String installerPackageName, int installerUid,
15828             int installReason) {
15829         if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
15830                 == PERMISSION_GRANTED) {
15831             // If the install is being performed by a system app, we trust that app to have set the
15832             // install reason correctly.
15833             return installReason;
15834         }
15835         final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
15836                 UserHandle.getUserId(installerUid));
15837         if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
15838             // If the install is being performed by a device or profile owner, the install
15839             // reason should be enterprise policy.
15840             return PackageManager.INSTALL_REASON_POLICY;
15841         }
15842 
15843 
15844         if (installReason == PackageManager.INSTALL_REASON_POLICY) {
15845             // If the install is being performed by a regular app (i.e. neither system app nor
15846             // device or profile owner), we have no reason to believe that the app is acting on
15847             // behalf of an enterprise. If the app set the install reason to enterprise policy,
15848             // change it to unknown instead.
15849             return PackageManager.INSTALL_REASON_UNKNOWN;
15850         }
15851 
15852         // If the install is being performed by a regular app and the install reason was set to any
15853         // value but enterprise policy, leave the install reason unchanged.
15854         return installReason;
15855     }
15856 
installStage(InstallParams params)15857     void installStage(InstallParams params) {
15858         final Message msg = mHandler.obtainMessage(INIT_COPY);
15859         params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
15860         msg.obj = params;
15861 
15862         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
15863                 System.identityHashCode(msg.obj));
15864         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
15865                 System.identityHashCode(msg.obj));
15866 
15867         mHandler.sendMessage(msg);
15868     }
15869 
installStage(InstallParams parent, List<InstallParams> children)15870     void installStage(InstallParams parent, List<InstallParams> children)
15871             throws PackageManagerException {
15872         final Message msg = mHandler.obtainMessage(INIT_COPY);
15873         final MultiPackageInstallParams params =
15874                 new MultiPackageInstallParams(parent, children);
15875         params.setTraceMethod("installStageMultiPackage")
15876                 .setTraceCookie(System.identityHashCode(params));
15877         msg.obj = params;
15878 
15879         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStageMultiPackage",
15880                 System.identityHashCode(msg.obj));
15881         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
15882                 System.identityHashCode(msg.obj));
15883         mHandler.sendMessage(msg);
15884     }
15885 
verifyStage(VerificationParams params)15886     void verifyStage(VerificationParams params) {
15887         mHandler.post(()-> {
15888             params.startCopy();
15889         });
15890     }
15891 
verifyStage(VerificationParams parent, List<VerificationParams> children)15892     void verifyStage(VerificationParams parent, List<VerificationParams> children)
15893             throws PackageManagerException {
15894         final MultiPackageVerificationParams params =
15895                 new MultiPackageVerificationParams(parent, children);
15896         mHandler.post(()-> {
15897             params.startCopy();
15898         });
15899     }
15900 
sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId, int dataLoaderType)15901     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
15902             int userId, int dataLoaderType) {
15903         final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
15904         final boolean isInstantApp = pkgSetting.getInstantApp(userId);
15905         final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
15906         final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
15907         sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
15908                 false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds,
15909                 dataLoaderType);
15910 
15911         // Send a session commit broadcast
15912         final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
15913         info.installReason = pkgSetting.getInstallReason(userId);
15914         info.appPackageName = packageName;
15915         sendSessionCommitBroadcast(info, userId);
15916     }
15917 
15918     @Override
sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted, boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds, int dataLoaderType)15919     public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
15920             boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds,
15921             int dataLoaderType) {
15922         if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
15923             return;
15924         }
15925         Bundle extras = new Bundle(1);
15926         // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
15927         final int uid = UserHandle.getUid(
15928                 (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
15929         extras.putInt(Intent.EXTRA_UID, uid);
15930         extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
15931 
15932         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
15933                 packageName, extras, 0, null, null, userIds, instantUserIds,
15934                 mAppsFilter.getVisibilityAllowList(
15935                         getPackageSettingInternal(packageName, Process.SYSTEM_UID),
15936                         userIds, mSettings.getPackagesLocked()), null);
15937         if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
15938             mHandler.post(() -> {
15939                         for (int userId : userIds) {
15940                             sendBootCompletedBroadcastToSystemApp(
15941                                     packageName, includeStopped, userId);
15942                         }
15943                     }
15944             );
15945         }
15946     }
15947 
15948     /**
15949      * The just-installed/enabled app is bundled on the system, so presumed to be able to run
15950      * automatically without needing an explicit launch.
15951      * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
15952      */
sendBootCompletedBroadcastToSystemApp( String packageName, boolean includeStopped, int userId)15953     private void sendBootCompletedBroadcastToSystemApp(
15954             String packageName, boolean includeStopped, int userId) {
15955         // If user is not running, the app didn't miss any broadcast
15956         if (!mUserManager.isUserRunning(userId)) {
15957             return;
15958         }
15959         final IActivityManager am = ActivityManager.getService();
15960         try {
15961             // Deliver LOCKED_BOOT_COMPLETED first
15962             Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
15963                     .setPackage(packageName);
15964             if (includeStopped) {
15965                 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15966             }
15967             final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
15968             final BroadcastOptions bOptions = getTemporaryAppAllowlistBroadcastOptions(
15969                     REASON_LOCKED_BOOT_COMPLETED);
15970             am.broadcastIntentWithFeature(null, null, lockedBcIntent, null, null, 0, null, null,
15971                     requiredPermissions, null, android.app.AppOpsManager.OP_NONE,
15972                     bOptions.toBundle(), false, false, userId);
15973 
15974             // Deliver BOOT_COMPLETED only if user is unlocked
15975             final UserManagerInternal umInternal = mInjector.getUserManagerInternal();
15976             if (umInternal.isUserUnlockingOrUnlocked(userId)) {
15977                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
15978                 if (includeStopped) {
15979                     bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15980                 }
15981                 am.broadcastIntentWithFeature(null, null, bcIntent, null, null, 0, null, null,
15982                         requiredPermissions, null, android.app.AppOpsManager.OP_NONE,
15983                         bOptions.toBundle(), false, false, userId);
15984             }
15985         } catch (RemoteException e) {
15986             throw e.rethrowFromSystemServer();
15987         }
15988     }
15989 
15990     @Override
setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId)15991     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
15992             int userId) {
15993         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15994         PackageSetting pkgSetting;
15995         final int callingUid = Binder.getCallingUid();
15996         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
15997                 true /* checkShell */, "setApplicationHiddenSetting for user " + userId);
15998 
15999         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
16000             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
16001             return false;
16002         }
16003 
16004         final long callingId = Binder.clearCallingIdentity();
16005         try {
16006             boolean sendAdded = false;
16007             boolean sendRemoved = false;
16008             // writer
16009             synchronized (mLock) {
16010                 pkgSetting = mSettings.getPackageLPr(packageName);
16011                 if (pkgSetting == null) {
16012                     return false;
16013                 }
16014                 if (shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
16015                     return false;
16016                 }
16017                 // Do not allow "android" is being disabled
16018                 if ("android".equals(packageName)) {
16019                     Slog.w(TAG, "Cannot hide package: android");
16020                     return false;
16021                 }
16022                 // Cannot hide static shared libs as they are considered
16023                 // a part of the using app (emulating static linking). Also
16024                 // static libs are installed always on internal storage.
16025                 AndroidPackage pkg = mPackages.get(packageName);
16026                 if (pkg != null && pkg.getStaticSharedLibName() != null) {
16027                     Slog.w(TAG, "Cannot hide package: " + packageName
16028                             + " providing static shared library: "
16029                             + pkg.getStaticSharedLibName());
16030                     return false;
16031                 }
16032                 // Only allow protected packages to hide themselves.
16033                 if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
16034                         && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
16035                     Slog.w(TAG, "Not hiding protected package: " + packageName);
16036                     return false;
16037                 }
16038 
16039                 if (pkgSetting.getHidden(userId) != hidden) {
16040                     pkgSetting.setHidden(hidden, userId);
16041                     mSettings.writePackageRestrictionsLPr(userId);
16042                     if (hidden) {
16043                         sendRemoved = true;
16044                     } else {
16045                         sendAdded = true;
16046                     }
16047                 }
16048             }
16049             if (sendAdded) {
16050                 sendPackageAddedForUser(packageName, pkgSetting, userId, DataLoaderType.NONE);
16051                 return true;
16052             }
16053             if (sendRemoved) {
16054                 killApplication(packageName, pkgSetting.appId, userId,
16055                         "hiding pkg");
16056                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
16057                 return true;
16058             }
16059         } finally {
16060             Binder.restoreCallingIdentity(callingId);
16061         }
16062         return false;
16063     }
16064 
16065     @Override
setSystemAppHiddenUntilInstalled(String packageName, boolean hidden)16066     public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
16067         final int callingUid = Binder.getCallingUid();
16068         final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
16069                 || callingUid == Process.SYSTEM_UID;
16070         if (!calledFromSystemOrPhone) {
16071             mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
16072                     "setSystemAppHiddenUntilInstalled");
16073         }
16074 
16075         synchronized (mLock) {
16076             final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
16077             if (pkgSetting == null || !pkgSetting.isSystem()) {
16078                 return;
16079             }
16080             if (pkgSetting.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
16081                 throw new SecurityException("Only system or phone callers can modify core apps");
16082             }
16083             pkgSetting.getPkgState().setHiddenUntilInstalled(hidden);
16084             final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
16085             if (disabledPs == null) {
16086                 return;
16087             }
16088             disabledPs.getPkgState().setHiddenUntilInstalled(hidden);
16089         }
16090     }
16091 
16092     @Override
setSystemAppInstallState(String packageName, boolean installed, int userId)16093     public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
16094         final int callingUid = Binder.getCallingUid();
16095         final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
16096                 || callingUid == Process.SYSTEM_UID;
16097         if (!calledFromSystemOrPhone) {
16098             mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
16099                     "setSystemAppHiddenUntilInstalled");
16100         }
16101 
16102         synchronized (mLock) {
16103             final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
16104             // The target app should always be in system
16105             if (pkgSetting == null || !pkgSetting.isSystem()) {
16106                 return false;
16107             }
16108             if (pkgSetting.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
16109                 throw new SecurityException("Only system or phone callers can modify core apps");
16110             }
16111             // Check if the install state is the same
16112             if (pkgSetting.getInstalled(userId) == installed) {
16113                 return false;
16114             }
16115         }
16116 
16117         final long callingId = Binder.clearCallingIdentity();
16118         try {
16119             if (installed) {
16120                 // install the app from uninstalled state
16121                 installExistingPackageAsUser(
16122                         packageName,
16123                         userId,
16124                         PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
16125                         PackageManager.INSTALL_REASON_DEVICE_SETUP,
16126                         null);
16127                 return true;
16128             }
16129 
16130             // uninstall the app from installed state
16131             deletePackageVersioned(
16132                     new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
16133                     new LegacyPackageDeleteObserver(null).getBinder(),
16134                     userId,
16135                     PackageManager.DELETE_SYSTEM_APP);
16136             return true;
16137         } finally {
16138             Binder.restoreCallingIdentity(callingId);
16139         }
16140     }
16141 
sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, int userId)16142     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
16143             int userId) {
16144         final PackageRemovedInfo info = new PackageRemovedInfo(this);
16145         info.removedPackage = packageName;
16146         info.installerPackageName = pkgSetting.installSource.installerPackageName;
16147         info.removedUsers = new int[] {userId};
16148         info.broadcastUsers = new int[] {userId};
16149         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
16150         info.sendPackageRemovedBroadcasts(true /*killApp*/, false /*removedBySystem*/);
16151     }
16152 
sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId, int distractionFlags)16153     private void sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId,
16154             int distractionFlags) {
16155         final Bundle extras = new Bundle(3);
16156         extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
16157         extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
16158         extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
16159         sendPackageBroadcast(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null, extras,
16160                 Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, new int[]{userId}, null, null,
16161                 null);
16162     }
16163 
16164     @VisibleForTesting(visibility = Visibility.PRIVATE)
sendPackagesSuspendedForUser(String intent, String[] pkgList, int[] uidList, int userId)16165     void sendPackagesSuspendedForUser(String intent, String[] pkgList, int[] uidList, int userId) {
16166         final List<List<String>> pkgsToSend = new ArrayList(pkgList.length);
16167         final List<IntArray> uidsToSend = new ArrayList(pkgList.length);
16168         final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length);
16169         final int[] userIds = new int[] {userId};
16170         // Get allow lists for the pkg in the pkgList. Merge into the existed pkgs and uids if
16171         // allow lists are the same.
16172         synchronized (mLock) {
16173             for (int i = 0; i < pkgList.length; i++) {
16174                 final String pkgName = pkgList[i];
16175                 final int uid = uidList[i];
16176                 SparseArray<int[]> allowList = mAppsFilter.getVisibilityAllowList(
16177                         getPackageSettingInternal(pkgName, Process.SYSTEM_UID),
16178                         userIds, mSettings.getPackagesLocked());
16179                 if (allowList == null) {
16180                     allowList = new SparseArray<>(0);
16181                 }
16182                 boolean merged = false;
16183                 for (int j = 0; j < allowListsToSend.size(); j++) {
16184                     if (Arrays.equals(allowListsToSend.get(j).get(userId), allowList.get(userId))) {
16185                         pkgsToSend.get(j).add(pkgName);
16186                         uidsToSend.get(j).add(uid);
16187                         merged = true;
16188                         break;
16189                     }
16190                 }
16191                 if (!merged) {
16192                     pkgsToSend.add(new ArrayList<>(Arrays.asList(pkgName)));
16193                     uidsToSend.add(IntArray.wrap(new int[] {uid}));
16194                     allowListsToSend.add(allowList);
16195                 }
16196             }
16197         }
16198 
16199         for (int i = 0; i < pkgsToSend.size(); i++) {
16200             final Bundle extras = new Bundle(3);
16201             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST,
16202                     pkgsToSend.get(i).toArray(new String[pkgsToSend.get(i).size()]));
16203             extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidsToSend.get(i).toArray());
16204             final SparseArray<int[]> allowList = allowListsToSend.get(i).size() == 0
16205                     ? null : allowListsToSend.get(i);
16206             sendPackageBroadcast(intent, null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null,
16207                     null, userIds, null, allowList, null);
16208         }
16209     }
16210 
16211     /**
16212      * Returns true if application is not found or there was an error. Otherwise it returns
16213      * the hidden state of the package for the given user.
16214      */
16215     @Override
getApplicationHiddenSettingAsUser(String packageName, int userId)16216     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
16217         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
16218         final int callingUid = Binder.getCallingUid();
16219         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
16220                 false /* checkShell */, "getApplicationHidden for user " + userId);
16221         PackageSetting ps;
16222         final long callingId = Binder.clearCallingIdentity();
16223         try {
16224             // writer
16225             synchronized (mLock) {
16226                 ps = mSettings.getPackageLPr(packageName);
16227                 if (ps == null) {
16228                     return true;
16229                 }
16230                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
16231                     return true;
16232                 }
16233                 return ps.getHidden(userId);
16234             }
16235         } finally {
16236             Binder.restoreCallingIdentity(callingId);
16237         }
16238     }
16239 
16240     /**
16241      * @hide
16242      */
16243     @Override
installExistingPackageAsUser(String packageName, int userId, int installFlags, int installReason, List<String> whiteListedPermissions)16244     public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
16245             int installReason, List<String> whiteListedPermissions) {
16246         return installExistingPackageAsUser(packageName, userId, installFlags, installReason,
16247                 whiteListedPermissions, null);
16248     }
16249 
installExistingPackageAsUser(@ullable String packageName, @UserIdInt int userId, @PackageManager.InstallFlags int installFlags, @PackageManager.InstallReason int installReason, @Nullable List<String> allowlistedRestrictedPermissions, @Nullable IntentSender intentSender)16250     int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
16251             @PackageManager.InstallFlags int installFlags,
16252             @PackageManager.InstallReason int installReason,
16253             @Nullable List<String> allowlistedRestrictedPermissions,
16254             @Nullable IntentSender intentSender) {
16255         if (DEBUG_INSTALL) {
16256             Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId
16257                     + " installFlags=" + installFlags + " installReason=" + installReason
16258                     + " allowlistedRestrictedPermissions=" + allowlistedRestrictedPermissions);
16259         }
16260 
16261         final int callingUid = Binder.getCallingUid();
16262         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
16263                 != PackageManager.PERMISSION_GRANTED
16264                 && mContext.checkCallingOrSelfPermission(
16265                         android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
16266                 != PackageManager.PERMISSION_GRANTED) {
16267             throw new SecurityException("Neither user " + callingUid + " nor current process has "
16268                     + android.Manifest.permission.INSTALL_PACKAGES + ".");
16269         }
16270         PackageSetting pkgSetting;
16271         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
16272                 true /* checkShell */, "installExistingPackage for user " + userId);
16273         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
16274             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
16275         }
16276 
16277         final long callingId = Binder.clearCallingIdentity();
16278         try {
16279             boolean installed = false;
16280             final boolean instantApp =
16281                     (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16282             final boolean fullApp =
16283                     (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
16284 
16285             // writer
16286             synchronized (mLock) {
16287                 pkgSetting = mSettings.getPackageLPr(packageName);
16288                 if (pkgSetting == null) {
16289                     return PackageManager.INSTALL_FAILED_INVALID_URI;
16290                 }
16291                 if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
16292                     // only allow the existing package to be used if it's installed as a full
16293                     // application for at least one user
16294                     boolean installAllowed = false;
16295                     for (int checkUserId : mUserManager.getUserIds()) {
16296                         installAllowed = !pkgSetting.getInstantApp(checkUserId);
16297                         if (installAllowed) {
16298                             break;
16299                         }
16300                     }
16301                     if (!installAllowed) {
16302                         return PackageManager.INSTALL_FAILED_INVALID_URI;
16303                     }
16304                 }
16305                 if (!pkgSetting.getInstalled(userId)) {
16306                     pkgSetting.setInstalled(true, userId);
16307                     pkgSetting.setHidden(false, userId);
16308                     pkgSetting.setInstallReason(installReason, userId);
16309                     pkgSetting.setUninstallReason(PackageManager.UNINSTALL_REASON_UNKNOWN, userId);
16310                     mSettings.writePackageRestrictionsLPr(userId);
16311                     mSettings.writeKernelMappingLPr(pkgSetting);
16312                     installed = true;
16313                 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
16314                     // upgrade app from instant to full; we don't allow app downgrade
16315                     installed = true;
16316                 }
16317                 setInstantAppForUser(mInjector, pkgSetting, userId, instantApp, fullApp);
16318             }
16319 
16320             if (installed) {
16321                 if (pkgSetting.pkg != null) {
16322                     final PermissionManagerServiceInternal.PackageInstalledParams.Builder
16323                             permissionParamsBuilder =
16324                             new PermissionManagerServiceInternal.PackageInstalledParams.Builder();
16325                     if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
16326                             != 0) {
16327                         permissionParamsBuilder.setAllowlistedRestrictedPermissions(
16328                                 pkgSetting.pkg.getRequestedPermissions());
16329                     }
16330                     mPermissionManager.onPackageInstalled(pkgSetting.pkg,
16331                             permissionParamsBuilder.build(), userId);
16332                 }
16333 
16334                 if (pkgSetting.pkg != null) {
16335                     synchronized (mInstallLock) {
16336                         // We don't need to freeze for a brand new install
16337                         prepareAppDataAfterInstallLIF(pkgSetting.pkg);
16338                     }
16339                 }
16340                 sendPackageAddedForUser(packageName, pkgSetting, userId, DataLoaderType.NONE);
16341                 synchronized (mLock) {
16342                     updateSequenceNumberLP(pkgSetting, new int[]{ userId });
16343                 }
16344                 // start async restore with no post-install since we finish install here
16345                 PackageInstalledInfo res =
16346                         createPackageInstalledInfo(PackageManager.INSTALL_SUCCEEDED);
16347                 res.pkg = pkgSetting.pkg;
16348                 res.newUsers = new int[]{ userId };
16349 
16350                 PostInstallData postInstallData =
16351                         new PostInstallData(null, res, () -> {
16352                             restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
16353                                     pkgSetting.getInstallReason(userId), userId);
16354                             if (intentSender != null) {
16355                                 onRestoreComplete(res.returnCode, mContext, intentSender);
16356                             }
16357                         });
16358                 restoreAndPostInstall(userId, res, postInstallData);
16359             }
16360         } finally {
16361             Binder.restoreCallingIdentity(callingId);
16362         }
16363 
16364         return PackageManager.INSTALL_SUCCEEDED;
16365     }
16366 
onRestoreComplete(int returnCode, Context context, IntentSender target)16367     static void onRestoreComplete(int returnCode, Context context, IntentSender target) {
16368         Intent fillIn = new Intent();
16369         fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
16370                 PackageManager.installStatusToPublicStatus(returnCode));
16371         try {
16372             target.sendIntent(context, 0, fillIn, null, null);
16373         } catch (SendIntentException ignored) {
16374         }
16375     }
16376 
setInstantAppForUser(Injector injector, PackageSetting pkgSetting, int userId, boolean instantApp, boolean fullApp)16377     static void setInstantAppForUser(Injector injector, PackageSetting pkgSetting,
16378             int userId, boolean instantApp, boolean fullApp) {
16379         // no state specified; do nothing
16380         if (!instantApp && !fullApp) {
16381             return;
16382         }
16383         if (userId != UserHandle.USER_ALL) {
16384             if (instantApp && !pkgSetting.getInstantApp(userId)) {
16385                 pkgSetting.setInstantApp(true /*instantApp*/, userId);
16386             } else if (fullApp && pkgSetting.getInstantApp(userId)) {
16387                 pkgSetting.setInstantApp(false /*instantApp*/, userId);
16388             }
16389         } else {
16390             for (int currentUserId : injector.getUserManagerInternal().getUserIds()) {
16391                 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
16392                     pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
16393                 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
16394                     pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
16395                 }
16396             }
16397         }
16398     }
16399 
isUserRestricted(int userId, String restrictionKey)16400     boolean isUserRestricted(int userId, String restrictionKey) {
16401         Bundle restrictions = mUserManager.getUserRestrictions(userId);
16402         if (restrictions.getBoolean(restrictionKey, false)) {
16403             Log.w(TAG, "User is restricted: " + restrictionKey);
16404             return true;
16405         }
16406         return false;
16407     }
16408 
16409     @Override
setDistractingPackageRestrictionsAsUser(String[] packageNames, int restrictionFlags, int userId)16410     public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
16411             int restrictionFlags, int userId) {
16412         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
16413                 "setDistractingPackageRestrictionsAsUser");
16414 
16415         final int callingUid = Binder.getCallingUid();
16416         if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
16417                 && UserHandle.getUserId(callingUid) != userId) {
16418             throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
16419                     + userId);
16420         }
16421         Objects.requireNonNull(packageNames, "packageNames cannot be null");
16422         if (restrictionFlags != 0 && !isSuspendAllowedForUser(userId)) {
16423             Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId);
16424             return packageNames;
16425         }
16426 
16427         final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
16428         final IntArray changedUids = new IntArray(packageNames.length);
16429         final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
16430         final boolean[] canRestrict = (restrictionFlags != 0) ? canSuspendPackageForUserInternal(
16431                 packageNames, userId) : null;
16432 
16433         for (int i = 0; i < packageNames.length; i++) {
16434             final String packageName = packageNames[i];
16435             final PackageSetting pkgSetting;
16436             synchronized (mLock) {
16437                 pkgSetting = mSettings.getPackageLPr(packageName);
16438                 if (pkgSetting == null
16439                         || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
16440                     Slog.w(TAG, "Could not find package setting for package: " + packageName
16441                             + ". Skipping...");
16442                     unactionedPackages.add(packageName);
16443                     continue;
16444                 }
16445             }
16446             if (canRestrict != null && !canRestrict[i]) {
16447                 unactionedPackages.add(packageName);
16448                 continue;
16449             }
16450             synchronized (mLock) {
16451                 final int oldDistractionFlags = pkgSetting.getDistractionFlags(userId);
16452                 if (restrictionFlags != oldDistractionFlags) {
16453                     pkgSetting.setDistractionFlags(restrictionFlags, userId);
16454                     changedPackagesList.add(packageName);
16455                     changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
16456                 }
16457             }
16458         }
16459 
16460         if (!changedPackagesList.isEmpty()) {
16461             final String[] changedPackages = changedPackagesList.toArray(
16462                     new String[changedPackagesList.size()]);
16463             sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
16464                     restrictionFlags);
16465             synchronized (mLock) {
16466                 scheduleWritePackageRestrictionsLocked(userId);
16467             }
16468         }
16469         return unactionedPackages.toArray(new String[0]);
16470     }
16471 
enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid, int userId, String callingMethod)16472     private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
16473             int userId, String callingMethod) {
16474         if (callingUid == Process.ROOT_UID
16475                 // Need to compare app-id to allow system dialogs access on secondary users
16476                 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
16477             return;
16478         }
16479 
16480         final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
16481         if (ownerPackage != null) {
16482             final int ownerUid = getPackageUid(ownerPackage, 0, userId);
16483             if (ownerUid == callingUid) {
16484                 return;
16485             }
16486         }
16487 
16488         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
16489                 callingMethod);
16490 
16491         final int packageUid = getPackageUid(callingPackage, 0, userId);
16492         final boolean allowedPackageUid = packageUid == callingUid;
16493         // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL
16494         final boolean allowedShell = callingUid == SHELL_UID
16495                 && UserHandle.isSameApp(packageUid, callingUid);
16496 
16497         if (!allowedShell && !allowedPackageUid) {
16498             throw new SecurityException("Calling package " + callingPackage + " in user "
16499                     + userId + " does not belong to calling uid " + callingUid);
16500         }
16501     }
16502 
16503     @Override
setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, SuspendDialogInfo dialogInfo, String callingPackage, int userId)16504     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
16505             PersistableBundle appExtras, PersistableBundle launcherExtras,
16506             SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
16507         final int callingUid = Binder.getCallingUid();
16508         enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
16509                 "setPackagesSuspendedAsUser");
16510 
16511         if (ArrayUtils.isEmpty(packageNames)) {
16512             return packageNames;
16513         }
16514         if (suspended && !isSuspendAllowedForUser(userId)) {
16515             Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
16516             return packageNames;
16517         }
16518 
16519         final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
16520         final IntArray changedUids = new IntArray(packageNames.length);
16521         final List<String> modifiedPackagesList = new ArrayList<>(packageNames.length);
16522         final IntArray modifiedUids = new IntArray(packageNames.length);
16523         final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
16524         final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
16525                 userId) : null;
16526 
16527         for (int i = 0; i < packageNames.length; i++) {
16528             final String packageName = packageNames[i];
16529             if (callingPackage.equals(packageName)) {
16530                 Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
16531                         + (suspended ? "" : "un") + "suspend itself. Ignoring");
16532                 unactionedPackages.add(packageName);
16533                 continue;
16534             }
16535             final PackageSetting pkgSetting;
16536             synchronized (mLock) {
16537                 pkgSetting = mSettings.getPackageLPr(packageName);
16538                 if (pkgSetting == null
16539                         || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
16540                     Slog.w(TAG, "Could not find package setting for package: " + packageName
16541                             + ". Skipping suspending/un-suspending.");
16542                     unactionedPackages.add(packageName);
16543                     continue;
16544                 }
16545             }
16546             if (canSuspend != null && !canSuspend[i]) {
16547                 unactionedPackages.add(packageName);
16548                 continue;
16549             }
16550             final boolean packageUnsuspended;
16551             final boolean packageModified;
16552             synchronized (mLock) {
16553                 if (suspended) {
16554                     packageModified = pkgSetting.addOrUpdateSuspension(callingPackage,
16555                             dialogInfo, appExtras, launcherExtras, userId);
16556                 } else {
16557                     packageModified = pkgSetting.removeSuspension(callingPackage, userId);
16558                 }
16559                 packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId);
16560             }
16561             if (suspended || packageUnsuspended) {
16562                 changedPackagesList.add(packageName);
16563                 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
16564             }
16565             if (packageModified) {
16566                 modifiedPackagesList.add(packageName);
16567                 modifiedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
16568             }
16569         }
16570 
16571         if (!changedPackagesList.isEmpty()) {
16572             final String[] changedPackages = changedPackagesList.toArray(new String[0]);
16573             sendPackagesSuspendedForUser(
16574                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
16575                               : Intent.ACTION_PACKAGES_UNSUSPENDED,
16576                     changedPackages, changedUids.toArray(), userId);
16577             sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId);
16578             synchronized (mLock) {
16579                 scheduleWritePackageRestrictionsLocked(userId);
16580             }
16581         }
16582         // Send the suspension changed broadcast to ensure suspension state is not stale.
16583         if (!modifiedPackagesList.isEmpty()) {
16584             sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED,
16585                     modifiedPackagesList.toArray(new String[0]), modifiedUids.toArray(), userId);
16586         }
16587         return unactionedPackages.toArray(new String[0]);
16588     }
16589 
16590     @Override
getSuspendedPackageAppExtras(String packageName, int userId)16591     public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
16592         final int callingUid = Binder.getCallingUid();
16593         if (getPackageUid(packageName, 0, userId) != callingUid) {
16594             throw new SecurityException("Calling package " + packageName
16595                     + " does not belong to calling uid " + callingUid);
16596         }
16597         return getSuspendedPackageAppExtrasInternal(packageName, userId);
16598     }
16599 
getSuspendedPackageAppExtrasInternal(String packageName, int userId)16600     private Bundle getSuspendedPackageAppExtrasInternal(String packageName, int userId) {
16601         synchronized (mLock) {
16602             final PackageSetting ps = mSettings.getPackageLPr(packageName);
16603             if (ps == null) {
16604                 return null;
16605             }
16606             final PackageUserState pus = ps.readUserState(userId);
16607             final Bundle allExtras = new Bundle();
16608             if (pus.suspended) {
16609                 for (int i = 0; i < pus.suspendParams.size(); i++) {
16610                     final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i);
16611                     if (params != null && params.appExtras != null) {
16612                         allExtras.putAll(params.appExtras);
16613                     }
16614                 }
16615             }
16616             return (allExtras.size() > 0) ? allExtras : null;
16617         }
16618     }
16619 
sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended, int userId)16620     private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
16621             int userId) {
16622         final String action = suspended
16623                 ? Intent.ACTION_MY_PACKAGE_SUSPENDED
16624                 : Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
16625         mHandler.post(() -> {
16626             final IActivityManager am = ActivityManager.getService();
16627             if (am == null) {
16628                 Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
16629                         + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
16630                 return;
16631             }
16632             final int[] targetUserIds = new int[] {userId};
16633             for (String packageName : affectedPackages) {
16634                 final Bundle appExtras = suspended
16635                         ? getSuspendedPackageAppExtrasInternal(packageName, userId)
16636                         : null;
16637                 final Bundle intentExtras;
16638                 if (appExtras != null) {
16639                     intentExtras = new Bundle(1);
16640                     intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, appExtras);
16641                 } else {
16642                     intentExtras = null;
16643                 }
16644                 doSendBroadcast(am, action, null, intentExtras,
16645                         Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
16646                         targetUserIds, false, null, null);
16647             }
16648         });
16649     }
16650 
16651     @Override
isPackageSuspendedForUser(String packageName, int userId)16652     public boolean isPackageSuspendedForUser(String packageName, int userId) {
16653         final int callingUid = Binder.getCallingUid();
16654         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
16655                 false /* checkShell */, "isPackageSuspendedForUser for user " + userId);
16656         synchronized (mLock) {
16657             final PackageSetting ps = mSettings.getPackageLPr(packageName);
16658             if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
16659                 throw new IllegalArgumentException("Unknown target package: " + packageName);
16660             }
16661             return ps.getSuspended(userId);
16662         }
16663     }
16664 
unsuspendForSuspendingPackage(String suspendingPackage, int userId)16665     void unsuspendForSuspendingPackage(String suspendingPackage, int userId) {
16666         final String[] allPackages;
16667         synchronized (mLock) {
16668             allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
16669         }
16670         removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId);
16671     }
16672 
isSuspendingAnyPackages(String suspendingPackage, int userId)16673     boolean isSuspendingAnyPackages(String suspendingPackage, int userId) {
16674         synchronized (mLock) {
16675             for (final PackageSetting ps : mSettings.getPackagesLocked().values()) {
16676                 if (ps.isSuspendedBy(suspendingPackage, userId)) {
16677                     return true;
16678                 }
16679             }
16680         }
16681         return false;
16682     }
16683 
16684     /**
16685      * Removes any suspensions on given packages that were added by packages that pass the given
16686      * predicate.
16687      *
16688      * <p> Caller must flush package restrictions if it cares about immediate data consistency.
16689      *
16690      * @param packagesToChange The packages on which the suspension are to be removed.
16691      * @param suspendingPackagePredicate A predicate identifying the suspending packages whose
16692      *                                   suspensions will be removed.
16693      * @param userId The user for which the changes are taking place.
16694      */
removeSuspensionsBySuspendingPackage(String[] packagesToChange, Predicate<String> suspendingPackagePredicate, int userId)16695     void removeSuspensionsBySuspendingPackage(String[] packagesToChange,
16696             Predicate<String> suspendingPackagePredicate, int userId) {
16697         final List<String> unsuspendedPackages = new ArrayList<>();
16698         final IntArray unsuspendedUids = new IntArray();
16699         synchronized (mLock) {
16700             for (String packageName : packagesToChange) {
16701                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
16702                 if (ps != null && ps.getSuspended(userId)) {
16703                     ps.removeSuspension(suspendingPackagePredicate, userId);
16704                     if (!ps.getSuspended(userId)) {
16705                         unsuspendedPackages.add(ps.name);
16706                         unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId()));
16707                     }
16708                 }
16709             }
16710             scheduleWritePackageRestrictionsLocked(userId);
16711         }
16712         if (!unsuspendedPackages.isEmpty()) {
16713             final String[] packageArray = unsuspendedPackages.toArray(
16714                     new String[unsuspendedPackages.size()]);
16715             sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
16716             sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_UNSUSPENDED,
16717                     packageArray, unsuspendedUids.toArray(), userId);
16718         }
16719     }
16720 
removeAllDistractingPackageRestrictions(int userId)16721     void removeAllDistractingPackageRestrictions(int userId) {
16722         final String[] allPackages;
16723         synchronized (mLock) {
16724             allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
16725         }
16726         removeDistractingPackageRestrictions(allPackages, userId);
16727     }
16728 
16729     /**
16730      * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions}
16731      * set on given packages.
16732      *
16733      * <p> Caller must flush package restrictions if it cares about immediate data consistency.
16734      *
16735      * @param packagesToChange The packages on which restrictions are to be removed.
16736      * @param userId the user for which changes are taking place.
16737      */
removeDistractingPackageRestrictions(String[] packagesToChange, int userId)16738     void removeDistractingPackageRestrictions(String[] packagesToChange, int userId) {
16739         final List<String> changedPackages = new ArrayList<>();
16740         final IntArray changedUids = new IntArray();
16741         synchronized (mLock) {
16742             for (String packageName : packagesToChange) {
16743                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
16744                 if (ps != null && ps.getDistractionFlags(userId) != 0) {
16745                     ps.setDistractionFlags(0, userId);
16746                     changedPackages.add(ps.name);
16747                     changedUids.add(UserHandle.getUid(userId, ps.getAppId()));
16748                 }
16749             }
16750             if (!changedPackages.isEmpty()) {
16751                 final String[] packageArray = changedPackages.toArray(
16752                         new String[changedPackages.size()]);
16753                 sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, 0);
16754                 scheduleWritePackageRestrictionsLocked(userId);
16755             }
16756         }
16757     }
16758 
isCallerDeviceOrProfileOwner(int userId)16759     private boolean isCallerDeviceOrProfileOwner(int userId) {
16760         final int callingUid = Binder.getCallingUid();
16761         if (callingUid == Process.SYSTEM_UID) {
16762             return true;
16763         }
16764         final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
16765         if (ownerPackage != null) {
16766             return callingUid == getPackageUidInternal(ownerPackage, 0, userId, callingUid);
16767         }
16768         return false;
16769     }
16770 
isSuspendAllowedForUser(int userId)16771     private boolean isSuspendAllowedForUser(int userId) {
16772         return isCallerDeviceOrProfileOwner(userId)
16773                 || (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)
16774                 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_UNINSTALL_APPS, userId));
16775     }
16776 
16777     @Override
getUnsuspendablePackagesForUser(String[] packageNames, int userId)16778     public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
16779         Objects.requireNonNull(packageNames, "packageNames cannot be null");
16780         mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
16781                 "getUnsuspendablePackagesForUser");
16782         final int callingUid = Binder.getCallingUid();
16783         if (UserHandle.getUserId(callingUid) != userId) {
16784             throw new SecurityException("Calling uid " + callingUid
16785                     + " cannot query getUnsuspendablePackagesForUser for user " + userId);
16786         }
16787         if (!isSuspendAllowedForUser(userId)) {
16788             Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
16789             return packageNames;
16790         }
16791         final ArraySet<String> unactionablePackages = new ArraySet<>();
16792         final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId);
16793         for (int i = 0; i < packageNames.length; i++) {
16794             if (!canSuspend[i]) {
16795                 unactionablePackages.add(packageNames[i]);
16796                 continue;
16797             }
16798             synchronized (mLock) {
16799                 final PackageSetting ps = mSettings.getPackageLPr(packageNames[i]);
16800                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
16801                     Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
16802                     unactionablePackages.add(packageNames[i]);
16803                 }
16804             }
16805         }
16806         return unactionablePackages.toArray(new String[unactionablePackages.size()]);
16807     }
16808 
16809     /**
16810      * Returns an array of booleans, such that the ith boolean denotes whether the ith package can
16811      * be suspended or not.
16812      *
16813      * @param packageNames  The package names to check suspendability for.
16814      * @param userId The user to check in
16815      * @return An array containing results of the checks
16816      */
16817     @NonNull
canSuspendPackageForUserInternal(@onNull String[] packageNames, int userId)16818     private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) {
16819         final boolean[] canSuspend = new boolean[packageNames.length];
16820         final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId);
16821         final long callingId = Binder.clearCallingIdentity();
16822         try {
16823             final String activeLauncherPackageName = mDefaultAppProvider.getDefaultHome(userId);
16824             final String dialerPackageName = mDefaultAppProvider.getDefaultDialer(userId);
16825             for (int i = 0; i < packageNames.length; i++) {
16826                 canSuspend[i] = false;
16827                 final String packageName = packageNames[i];
16828 
16829                 if (isPackageDeviceAdmin(packageName, userId)) {
16830                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16831                             + "\": has an active device admin");
16832                     continue;
16833                 }
16834                 if (packageName.equals(activeLauncherPackageName)) {
16835                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16836                             + "\": contains the active launcher");
16837                     continue;
16838                 }
16839                 if (packageName.equals(mRequiredInstallerPackage)) {
16840                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16841                             + "\": required for package installation");
16842                     continue;
16843                 }
16844                 if (packageName.equals(mRequiredUninstallerPackage)) {
16845                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16846                             + "\": required for package uninstallation");
16847                     continue;
16848                 }
16849                 if (packageName.equals(mRequiredVerifierPackage)) {
16850                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16851                             + "\": required for package verification");
16852                     continue;
16853                 }
16854                 if (packageName.equals(dialerPackageName)) {
16855                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16856                             + "\": is the default dialer");
16857                     continue;
16858                 }
16859                 if (packageName.equals(mRequiredPermissionControllerPackage)) {
16860                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16861                             + "\": required for permissions management");
16862                     continue;
16863                 }
16864                 synchronized (mLock) {
16865                     if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
16866                         Slog.w(TAG, "Cannot suspend package \"" + packageName
16867                                 + "\": protected package");
16868                         continue;
16869                     }
16870                     if (!isCallerOwner && mSettings.getBlockUninstallLPr(userId, packageName)) {
16871                         Slog.w(TAG, "Cannot suspend package \"" + packageName
16872                                 + "\": blocked by admin");
16873                         continue;
16874                     }
16875 
16876                     // Cannot suspend static shared libs as they are considered
16877                     // a part of the using app (emulating static linking). Also
16878                     // static libs are installed always on internal storage.
16879                     AndroidPackage pkg = mPackages.get(packageName);
16880                     if (pkg != null && pkg.isStaticSharedLibrary()) {
16881                         Slog.w(TAG, "Cannot suspend package: " + packageName
16882                                 + " providing static shared library: "
16883                                 + pkg.getStaticSharedLibName());
16884                         continue;
16885                     }
16886                 }
16887                 if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
16888                     Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
16889                     continue;
16890                 }
16891                 canSuspend[i] = true;
16892             }
16893         } finally {
16894             Binder.restoreCallingIdentity(callingId);
16895         }
16896         return canSuspend;
16897     }
16898 
16899     @Override
verifyPendingInstall(int id, int verificationCode)16900     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
16901         mContext.enforceCallingOrSelfPermission(
16902                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16903                 "Only package verification agents can verify applications");
16904 
16905         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
16906         final PackageVerificationResponse response = new PackageVerificationResponse(
16907                 verificationCode, Binder.getCallingUid());
16908         msg.arg1 = id;
16909         msg.obj = response;
16910         mHandler.sendMessage(msg);
16911     }
16912 
16913     @Override
extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)16914     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
16915             long millisecondsToDelay) {
16916         mContext.enforceCallingOrSelfPermission(
16917                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16918                 "Only package verification agents can extend verification timeouts");
16919 
16920         final PackageVerificationState state = mPendingVerification.get(id);
16921         final PackageVerificationResponse response = new PackageVerificationResponse(
16922                 verificationCodeAtTimeout, Binder.getCallingUid());
16923 
16924         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
16925             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
16926         }
16927         if (millisecondsToDelay < 0) {
16928             millisecondsToDelay = 0;
16929         }
16930         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
16931                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
16932             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
16933         }
16934 
16935         if ((state != null) && !state.timeoutExtended()) {
16936             state.extendTimeout();
16937 
16938             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
16939             msg.arg1 = id;
16940             msg.obj = response;
16941             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
16942         }
16943     }
16944 
broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, @Nullable String rootHashString, int dataLoaderType, UserHandle user)16945     private void broadcastPackageVerified(int verificationId, Uri packageUri,
16946             int verificationCode, @Nullable String rootHashString, int dataLoaderType,
16947             UserHandle user) {
16948         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
16949         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
16950         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
16951         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
16952         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
16953         if (rootHashString != null) {
16954             intent.putExtra(PackageManager.EXTRA_VERIFICATION_ROOT_HASH, rootHashString);
16955         }
16956         intent.putExtra(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
16957 
16958         mContext.sendBroadcastAsUser(intent, user,
16959                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
16960     }
16961 
matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)16962     private ComponentName matchComponentForVerifier(String packageName,
16963             List<ResolveInfo> receivers) {
16964         ActivityInfo targetReceiver = null;
16965 
16966         final int NR = receivers.size();
16967         for (int i = 0; i < NR; i++) {
16968             final ResolveInfo info = receivers.get(i);
16969             if (info.activityInfo == null) {
16970                 continue;
16971             }
16972 
16973             if (packageName.equals(info.activityInfo.packageName)) {
16974                 targetReceiver = info.activityInfo;
16975                 break;
16976             }
16977         }
16978 
16979         if (targetReceiver == null) {
16980             return null;
16981         }
16982 
16983         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
16984     }
16985 
matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)16986     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
16987             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
16988         if (pkgInfo.verifiers.length == 0) {
16989             return null;
16990         }
16991 
16992         final int N = pkgInfo.verifiers.length;
16993         final List<ComponentName> sufficientVerifiers = new ArrayList<>(N + 1);
16994         for (int i = 0; i < N; i++) {
16995             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
16996 
16997             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
16998                     receivers);
16999             if (comp == null) {
17000                 continue;
17001             }
17002 
17003             final int verifierUid = getUidForVerifier(verifierInfo);
17004             if (verifierUid == -1) {
17005                 continue;
17006             }
17007 
17008             if (DEBUG_VERIFY) {
17009                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
17010                         + " with the correct signature");
17011             }
17012             sufficientVerifiers.add(comp);
17013             verificationState.addSufficientVerifier(verifierUid);
17014         }
17015 
17016         return sufficientVerifiers;
17017     }
17018 
getUidForVerifier(VerifierInfo verifierInfo)17019     private int getUidForVerifier(VerifierInfo verifierInfo) {
17020         synchronized (mLock) {
17021             final AndroidPackage pkg = mPackages.get(verifierInfo.packageName);
17022             if (pkg == null) {
17023                 return -1;
17024             } else if (pkg.getSigningDetails().signatures.length != 1) {
17025                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
17026                         + " has more than one signature; ignoring");
17027                 return -1;
17028             }
17029 
17030             /*
17031              * If the public key of the package's signature does not match
17032              * our expected public key, then this is a different package and
17033              * we should skip.
17034              */
17035 
17036             final byte[] expectedPublicKey;
17037             try {
17038                 final Signature verifierSig = pkg.getSigningDetails().signatures[0];
17039                 final PublicKey publicKey = verifierSig.getPublicKey();
17040                 expectedPublicKey = publicKey.getEncoded();
17041             } catch (CertificateException e) {
17042                 return -1;
17043             }
17044 
17045             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
17046 
17047             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
17048                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
17049                         + " does not have the expected public key; ignoring");
17050                 return -1;
17051             }
17052 
17053             return pkg.getUid();
17054         }
17055     }
17056 
setEnableRollbackCode(int token, int enableRollbackCode)17057     private void setEnableRollbackCode(int token, int enableRollbackCode) {
17058         final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
17059         msg.arg1 = token;
17060         msg.arg2 = enableRollbackCode;
17061         mHandler.sendMessage(msg);
17062     }
17063 
17064     @Override
finishPackageInstall(int token, boolean didLaunch)17065     public void finishPackageInstall(int token, boolean didLaunch) {
17066         enforceSystemOrRoot("Only the system is allowed to finish installs");
17067 
17068         if (DEBUG_INSTALL) {
17069             Slog.v(TAG, "BM finishing package install for " + token);
17070         }
17071         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
17072 
17073         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
17074         mHandler.sendMessage(msg);
17075     }
17076 
17077     /**
17078      * Get the verification agent timeout.  Used for both the APK verifier and the
17079      * intent filter verifier.
17080      *
17081      * @return verification timeout in milliseconds
17082      */
getVerificationTimeout()17083     private long getVerificationTimeout() {
17084         long timeout = Global.getLong(mContext.getContentResolver(),
17085                 Global.PACKAGE_VERIFIER_TIMEOUT, DEFAULT_VERIFICATION_TIMEOUT);
17086         // The setting can be used to increase the timeout but not decrease it, since that is
17087         // equivalent to disabling the verifier.
17088         return Math.max(timeout, DEFAULT_VERIFICATION_TIMEOUT);
17089     }
17090 
17091     /**
17092      * Get the integrity verification timeout.
17093      *
17094      * @return verification timeout in milliseconds
17095      */
getIntegrityVerificationTimeout()17096     private long getIntegrityVerificationTimeout() {
17097         long timeout = Global.getLong(mContext.getContentResolver(),
17098                 Global.APP_INTEGRITY_VERIFICATION_TIMEOUT, DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
17099         // The setting can be used to increase the timeout but not decrease it, since that is
17100         // equivalent to disabling the integrity component.
17101         return Math.max(timeout, DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
17102     }
17103 
17104     /**
17105      * Get the default verification agent response code.
17106      *
17107      * @return default verification response code
17108      */
getDefaultVerificationResponse(UserHandle user)17109     private int getDefaultVerificationResponse(UserHandle user) {
17110         if (mUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
17111             return PackageManager.VERIFICATION_REJECT;
17112         }
17113         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
17114                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
17115                 DEFAULT_VERIFICATION_RESPONSE);
17116     }
17117 
17118     /**
17119      * Get the default integrity verification response code.
17120      */
getDefaultIntegrityVerificationResponse()17121     private int getDefaultIntegrityVerificationResponse() {
17122         // We are not exposing this as a user-configurable setting because we don't want to provide
17123         // an easy way to get around the integrity check.
17124         return PackageManager.VERIFICATION_REJECT;
17125     }
17126 
17127     /**
17128      * Check whether or not package verification has been enabled.
17129      *
17130      * @return true if verification should be performed
17131      */
isVerificationEnabled( PackageInfoLite pkgInfoLite, int userId, int installFlags, int installerUid)17132     private boolean isVerificationEnabled(
17133             PackageInfoLite pkgInfoLite, int userId, int installFlags, int installerUid) {
17134         if (!DEFAULT_VERIFY_ENABLE) {
17135             return false;
17136         }
17137 
17138         // Check if installing from ADB
17139         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
17140             if (isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS)) {
17141                 return true;
17142             }
17143             // Check if the developer wants to skip verification for ADB installs
17144             if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
17145                 synchronized (mLock) {
17146                     if (mSettings.getPackageLPr(pkgInfoLite.packageName) == null) {
17147                         // Always verify fresh install
17148                         return true;
17149                     }
17150                 }
17151                 // Only skip when apk is debuggable
17152                 return !pkgInfoLite.debuggable;
17153             }
17154             return Global.getInt(mContext.getContentResolver(),
17155                     Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
17156         }
17157 
17158         // only when not installed from ADB, skip verification for instant apps when
17159         // the installer and verifier are the same.
17160         if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
17161             if (mInstantAppInstallerActivity != null
17162                     && mInstantAppInstallerActivity.packageName.equals(
17163                             mRequiredVerifierPackage)) {
17164                 try {
17165                     mInjector.getSystemService(AppOpsManager.class)
17166                             .checkPackage(installerUid, mRequiredVerifierPackage);
17167                     if (DEBUG_VERIFY) {
17168                         Slog.i(TAG, "disable verification for instant app");
17169                     }
17170                     return false;
17171                 } catch (SecurityException ignore) { }
17172             }
17173         }
17174         return true;
17175     }
17176 
17177     /**
17178      * Check whether or not integrity verification has been enabled.
17179      */
isIntegrityVerificationEnabled()17180     private boolean isIntegrityVerificationEnabled() {
17181         // We are not exposing this as a user-configurable setting because we don't want to provide
17182         // an easy way to get around the integrity check.
17183         return DEFAULT_INTEGRITY_VERIFY_ENABLE;
17184     }
17185 
17186     @Deprecated
17187     @Override
verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)17188     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
17189         DomainVerificationProxyV1.queueLegacyVerifyResult(mContext, mDomainVerificationConnection,
17190                 id, verificationCode, failedDomains, Binder.getCallingUid());
17191     }
17192 
17193     @Deprecated
17194     @Override
getIntentVerificationStatus(String packageName, int userId)17195     public int getIntentVerificationStatus(String packageName, int userId) {
17196         return mDomainVerificationManager.getLegacyState(packageName, userId);
17197     }
17198 
17199     @Deprecated
17200     @Override
updateIntentVerificationStatus(String packageName, int status, int userId)17201     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
17202         return mDomainVerificationManager.setLegacyUserState(packageName, userId, status);
17203     }
17204 
17205     @Deprecated
17206     @Override
getIntentFilterVerifications( String packageName)17207     public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
17208             String packageName) {
17209         return ParceledListSlice.emptyList();
17210     }
17211 
17212     @Override
getAllIntentFilters(String packageName)17213     public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
17214         if (TextUtils.isEmpty(packageName)) {
17215             return ParceledListSlice.emptyList();
17216         }
17217         final int callingUid = Binder.getCallingUid();
17218         final int callingUserId = UserHandle.getUserId(callingUid);
17219         synchronized (mLock) {
17220             AndroidPackage pkg = mPackages.get(packageName);
17221             if (pkg == null || ArrayUtils.isEmpty(pkg.getActivities())) {
17222                 return ParceledListSlice.emptyList();
17223             }
17224             final PackageSetting ps = getPackageSetting(pkg.getPackageName());
17225             if (ps == null) {
17226                 return ParceledListSlice.emptyList();
17227             }
17228             if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
17229                 return ParceledListSlice.emptyList();
17230             }
17231             final int count = ArrayUtils.size(pkg.getActivities());
17232             ArrayList<IntentFilter> result = new ArrayList<>();
17233             for (int n=0; n<count; n++) {
17234                 ParsedActivity activity = pkg.getActivities().get(n);
17235                 if (activity.getIntents() != null && activity.getIntents().size() > 0) {
17236                     result.addAll(activity.getIntents());
17237                 }
17238             }
17239             return new ParceledListSlice<IntentFilter>(result) {
17240                 @Override
17241                 protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) {
17242                     parcelable.writeToParcel(dest, callFlags);
17243                 }
17244 
17245                 @Override
17246                 protected void writeParcelableCreator(IntentFilter parcelable, Parcel dest) {
17247                     // All Parcel#writeParcelableCreator does is serialize the class name to
17248                     // access via reflection to grab its CREATOR. This does that manually, pointing
17249                     // to the parent IntentFilter so that all of the subclass fields are ignored.
17250                     dest.writeString(IntentFilter.class.getName());
17251                 }
17252             };
17253         }
17254     }
17255 
17256     /**
17257      * Get the "allow unknown sources" setting.
17258      *
17259      * @return the current "allow unknown sources" setting
17260      */
getUnknownSourcesSettings()17261     private int getUnknownSourcesSettings() {
17262         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
17263                 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
17264                 -1);
17265     }
17266 
17267     @Override
setInstallerPackageName(String targetPackage, String installerPackageName)17268     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
17269         final int callingUid = Binder.getCallingUid();
17270         final int callingUserId = UserHandle.getUserId(callingUid);
17271         if (getInstantAppPackageName(callingUid) != null) {
17272             return;
17273         }
17274         // writer
17275         synchronized (mLock) {
17276             PackageSetting targetPackageSetting = mSettings.getPackageLPr(targetPackage);
17277             if (targetPackageSetting == null
17278                     || shouldFilterApplicationLocked(
17279                             targetPackageSetting, callingUid, callingUserId)) {
17280                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
17281             }
17282 
17283             PackageSetting installerPackageSetting;
17284             if (installerPackageName != null) {
17285                 installerPackageSetting = mSettings.getPackageLPr(installerPackageName);
17286                 if (installerPackageSetting == null
17287                         || shouldFilterApplicationLocked(
17288                                 installerPackageSetting, callingUid, callingUserId)) {
17289                     throw new IllegalArgumentException("Unknown installer package: "
17290                             + installerPackageName);
17291                 }
17292             } else {
17293                 installerPackageSetting = null;
17294             }
17295 
17296             Signature[] callerSignature;
17297             final int appId = UserHandle.getAppId(callingUid);
17298             final Object obj = mSettings.getSettingLPr(appId);
17299             if (obj != null) {
17300                 if (obj instanceof SharedUserSetting) {
17301                     callerSignature =
17302                             ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
17303                 } else if (obj instanceof PackageSetting) {
17304                     callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
17305                 } else {
17306                     throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
17307                 }
17308             } else {
17309                 throw new SecurityException("Unknown calling UID: " + callingUid);
17310             }
17311 
17312             // Verify: can't set installerPackageName to a package that is
17313             // not signed with the same cert as the caller.
17314             if (installerPackageSetting != null) {
17315                 if (compareSignatures(callerSignature,
17316                         installerPackageSetting.signatures.mSigningDetails.signatures)
17317                         != PackageManager.SIGNATURE_MATCH) {
17318                     throw new SecurityException(
17319                             "Caller does not have same cert as new installer package "
17320                             + installerPackageName);
17321                 }
17322             }
17323 
17324             // Verify: if target already has an installer package, it must
17325             // be signed with the same cert as the caller.
17326             String targetInstallerPackageName =
17327                     targetPackageSetting.installSource.installerPackageName;
17328             PackageSetting targetInstallerPkgSetting = targetInstallerPackageName == null ? null :
17329                     mSettings.getPackageLPr(targetInstallerPackageName);
17330 
17331             if (targetInstallerPkgSetting != null) {
17332                 if (compareSignatures(callerSignature,
17333                         targetInstallerPkgSetting.signatures.mSigningDetails.signatures)
17334                         != PackageManager.SIGNATURE_MATCH) {
17335                     throw new SecurityException(
17336                             "Caller does not have same cert as old installer package "
17337                             + targetInstallerPackageName);
17338                 }
17339             } else if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
17340                     != PackageManager.PERMISSION_GRANTED) {
17341                 // This is probably an attempt to exploit vulnerability b/150857253 of taking
17342                 // privileged installer permissions when the installer has been uninstalled or
17343                 // was never set.
17344                 EventLog.writeEvent(0x534e4554, "150857253", callingUid, "");
17345 
17346                 final long binderToken = Binder.clearCallingIdentity();
17347                 try {
17348                     if (mInjector.getCompatibility().isChangeEnabledByUid(
17349                             THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE,
17350                             callingUid)) {
17351                         throw new SecurityException("Neither user " + callingUid
17352                                 + " nor current process has "
17353                                 + Manifest.permission.INSTALL_PACKAGES);
17354                     } else {
17355                         // If change disabled, fail silently for backwards compatibility
17356                         return;
17357                     }
17358                 } finally {
17359                     Binder.restoreCallingIdentity(binderToken);
17360                 }
17361             }
17362 
17363             // Okay!
17364             targetPackageSetting.setInstallerPackageName(installerPackageName);
17365             mSettings.addInstallerPackageNames(targetPackageSetting.installSource);
17366             mAppsFilter.addPackage(targetPackageSetting);
17367             scheduleWriteSettingsLocked();
17368         }
17369     }
17370 
17371     @Override
setApplicationCategoryHint(String packageName, int categoryHint, String callerPackageName)17372     public void setApplicationCategoryHint(String packageName, int categoryHint,
17373             String callerPackageName) {
17374         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
17375             throw new SecurityException("Instant applications don't have access to this method");
17376         }
17377         mInjector.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
17378                 callerPackageName);
17379         synchronized (mLock) {
17380             PackageSetting ps = mSettings.getPackageLPr(packageName);
17381             if (ps == null || shouldFilterApplicationLocked(
17382                     ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
17383                 throw new IllegalArgumentException("Unknown target package " + packageName);
17384             }
17385             if (!Objects.equals(callerPackageName, ps.installSource.installerPackageName)) {
17386                 throw new IllegalArgumentException("Calling package " + callerPackageName
17387                         + " is not installer for " + packageName);
17388             }
17389 
17390             if (ps.categoryHint != categoryHint) {
17391                 ps.categoryHint = categoryHint;
17392                 scheduleWriteSettingsLocked();
17393             }
17394         }
17395     }
17396 
17397     // Queue up an async operation since the package installation may take a little while.
processInstallRequestsAsync(boolean success, List<InstallRequest> installRequests)17398     private void processInstallRequestsAsync(boolean success,
17399             List<InstallRequest> installRequests) {
17400         mHandler.post(() -> {
17401             List<InstallRequest> apexInstallRequests = new ArrayList<>();
17402             List<InstallRequest> apkInstallRequests = new ArrayList<>();
17403             for (InstallRequest request : installRequests) {
17404                 if ((request.args.installFlags & PackageManager.INSTALL_APEX) != 0) {
17405                     apexInstallRequests.add(request);
17406                 } else {
17407                     apkInstallRequests.add(request);
17408                 }
17409             }
17410             // Note: supporting multi package install of both APEXes and APKs might requir some
17411             // thinking to ensure atomicity of the install.
17412             if (!apexInstallRequests.isEmpty() && !apkInstallRequests.isEmpty()) {
17413                 // This should've been caught at the validation step, but for some reason wasn't.
17414                 throw new IllegalStateException(
17415                         "Attempted to do a multi package install of both APEXes and APKs");
17416             }
17417             if (!apexInstallRequests.isEmpty()) {
17418                 if (success) {
17419                     // Since installApexPackages requires talking to external service (apexd), we
17420                     // schedule to run it async. Once it finishes, it will resume the install.
17421                     Thread t = new Thread(() -> installApexPackagesTraced(apexInstallRequests),
17422                             "installApexPackages");
17423                     t.start();
17424                 } else {
17425                     // Non-staged APEX installation failed somewhere before
17426                     // processInstallRequestAsync. In that case just notify the observer about the
17427                     // failure.
17428                     InstallRequest request = apexInstallRequests.get(0);
17429                     notifyInstallObserver(request.installResult, request.args.observer);
17430                 }
17431                 return;
17432             }
17433             if (success) {
17434                 for (InstallRequest request : apkInstallRequests) {
17435                     request.args.doPreInstall(request.installResult.returnCode);
17436                 }
17437                 synchronized (mInstallLock) {
17438                     installPackagesTracedLI(apkInstallRequests);
17439                 }
17440                 for (InstallRequest request : apkInstallRequests) {
17441                     request.args.doPostInstall(
17442                             request.installResult.returnCode, request.installResult.uid);
17443                 }
17444             }
17445             for (InstallRequest request : apkInstallRequests) {
17446                 restoreAndPostInstall(request.args.user.getIdentifier(), request.installResult,
17447                         new PostInstallData(request.args, request.installResult, null));
17448             }
17449         });
17450     }
17451 
installApexPackagesTraced(List<InstallRequest> requests)17452     private void installApexPackagesTraced(List<InstallRequest> requests) {
17453         try {
17454             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installApexPackages");
17455             installApexPackages(requests);
17456         } finally {
17457             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17458         }
17459     }
17460 
installApexPackages(List<InstallRequest> requests)17461     private void installApexPackages(List<InstallRequest> requests) {
17462         if (requests.isEmpty()) {
17463             return;
17464         }
17465         if (requests.size() != 1) {
17466             throw new IllegalStateException(
17467                 "Only a non-staged install of a single APEX is supported");
17468         }
17469         InstallRequest request = requests.get(0);
17470         try {
17471             // Should directory scanning logic be moved to ApexManager for better test coverage?
17472             final File dir = request.args.origin.resolvedFile;
17473             final File[] apexes = dir.listFiles();
17474             if (apexes == null) {
17475                 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
17476                         dir.getAbsolutePath() + " is not a directory");
17477             }
17478             if (apexes.length != 1) {
17479                 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
17480                         "Expected exactly one .apex file under " + dir.getAbsolutePath()
17481                                 + " got: " + apexes.length);
17482             }
17483             try (PackageParser2 packageParser = mInjector.getScanningPackageParser()) {
17484                 mApexManager.installPackage(apexes[0], packageParser);
17485             }
17486         } catch (PackageManagerException e) {
17487             request.installResult.setError("APEX installation failed", e);
17488         }
17489         invalidatePackageInfoCache();
17490         notifyInstallObserver(request.installResult, request.args.observer);
17491     }
17492 
createPackageInstalledInfo( int currentStatus)17493     private PackageInstalledInfo createPackageInstalledInfo(
17494             int currentStatus) {
17495         PackageInstalledInfo res = new PackageInstalledInfo();
17496         res.setReturnCode(currentStatus);
17497         res.uid = -1;
17498         res.pkg = null;
17499         res.removedInfo = null;
17500         return res;
17501     }
17502 
17503     /** @param data Post-install is performed only if this is non-null. */
restoreAndPostInstall( int userId, PackageInstalledInfo res, @Nullable PostInstallData data)17504     private void restoreAndPostInstall(
17505             int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
17506         if (DEBUG_INSTALL) {
17507             Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.pkg);
17508         }
17509 
17510         // A restore should be requested at this point if (a) the install
17511         // succeeded, (b) the operation is not an update.
17512         final boolean update = res.removedInfo != null
17513                 && res.removedInfo.removedPackage != null;
17514         boolean doRestore = !update && res.pkg != null;
17515 
17516         // Set up the post-install work request bookkeeping.  This will be used
17517         // and cleaned up by the post-install event handling regardless of whether
17518         // there's a restore pass performed.  Token values are >= 1.
17519         int token;
17520         if (mNextInstallToken < 0) mNextInstallToken = 1;
17521         token = mNextInstallToken++;
17522         if (data != null) {
17523             mRunningInstalls.put(token, data);
17524         } else if (DEBUG_INSTALL) {
17525             Log.v(TAG, "No post-install required for " + token);
17526         }
17527 
17528         if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
17529 
17530         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
17531             // Pass responsibility to the Backup Manager.  It will perform a
17532             // restore if appropriate, then pass responsibility back to the
17533             // Package Manager to run the post-install observer callbacks
17534             // and broadcasts.
17535             if (res.freezer != null) {
17536                 res.freezer.close();
17537             }
17538             doRestore = performBackupManagerRestore(userId, token, res);
17539         }
17540 
17541         // If this is an update to a package that might be potentially downgraded, then we
17542         // need to check with the rollback manager whether there's any userdata that might
17543         // need to be snapshotted or restored for the package.
17544         //
17545         // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL.
17546         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
17547             doRestore = performRollbackManagerRestore(userId, token, res, data);
17548         }
17549 
17550         if (!doRestore) {
17551             // No restore possible, or the Backup Manager was mysteriously not
17552             // available -- just fire the post-install work request directly.
17553             if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
17554 
17555             Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
17556 
17557             Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
17558             mHandler.sendMessage(msg);
17559         }
17560     }
17561 
17562     /**
17563      * Perform Backup Manager restore for a given {@link PackageInstalledInfo}.
17564      * Returns whether the restore successfully completed.
17565      */
performBackupManagerRestore(int userId, int token, PackageInstalledInfo res)17566     private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) {
17567         IBackupManager bm = IBackupManager.Stub.asInterface(
17568                 ServiceManager.getService(Context.BACKUP_SERVICE));
17569         if (bm != null) {
17570             // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
17571             // in the BackupManager. USER_ALL is used in compatibility tests.
17572             if (userId == UserHandle.USER_ALL) {
17573                 userId = UserHandle.USER_SYSTEM;
17574             }
17575             if (DEBUG_INSTALL) {
17576                 Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId);
17577             }
17578             Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
17579             try {
17580                 if (bm.isUserReadyForBackup(userId)) {
17581                     bm.restoreAtInstallForUser(
17582                             userId, res.pkg.getPackageName(), token);
17583                 } else {
17584                     Slog.w(TAG, "User " + userId + " is not ready. Restore at install "
17585                             + "didn't take place.");
17586                     return false;
17587                 }
17588             } catch (RemoteException e) {
17589                 // can't happen; the backup manager is local
17590             } catch (Exception e) {
17591                 Slog.e(TAG, "Exception trying to enqueue restore", e);
17592                 return false;
17593             }
17594         } else {
17595             Slog.e(TAG, "Backup Manager not found!");
17596             return false;
17597         }
17598         return true;
17599     }
17600 
17601     /**
17602      * Perform Rollback Manager restore for a given {@link PackageInstalledInfo}.
17603      * Returns whether the restore successfully completed.
17604      */
performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res, PostInstallData data)17605     private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res,
17606             PostInstallData data) {
17607         RollbackManagerInternal rm = mInjector.getLocalService(RollbackManagerInternal.class);
17608 
17609         final String packageName = res.pkg.getPackageName();
17610         final int[] allUsers = mUserManager.getUserIds();
17611         final int[] installedUsers;
17612 
17613         final PackageSetting ps;
17614         int appId = -1;
17615         long ceDataInode = -1;
17616         synchronized (mLock) {
17617             ps = mSettings.getPackageLPr(packageName);
17618             if (ps != null) {
17619                 appId = ps.appId;
17620                 ceDataInode = ps.getCeDataInode(userId);
17621             }
17622 
17623             // NOTE: We ignore the user specified in the InstallParam because we know this is
17624             // an update, and hence need to restore data for all installed users.
17625             installedUsers = ps.queryInstalledUsers(allUsers, true);
17626         }
17627 
17628         boolean doSnapshotOrRestore = data != null && data.args != null
17629                 && ((data.args.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0
17630                 || (data.args.installFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0);
17631 
17632         if (ps != null && doSnapshotOrRestore) {
17633             final String seInfo = AndroidPackageUtils.getSeInfo(res.pkg, ps);
17634             rm.snapshotAndRestoreUserData(packageName, UserHandle.toUserHandles(installedUsers),
17635                     appId, ceDataInode, seInfo, token);
17636             return true;
17637         }
17638         return false;
17639     }
17640 
17641     /**
17642      * Callback from PackageSettings whenever an app is first transitioned out of the
17643      * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
17644      * the app was "launched" for a restoreAtInstall operation.  Therefore we check
17645      * here whether the app is the target of an ongoing install, and only send the
17646      * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
17647      * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
17648      * handling.
17649      */
notifyFirstLaunch(final String packageName, final String installerPackage, final int userId)17650     void notifyFirstLaunch(final String packageName, final String installerPackage,
17651             final int userId) {
17652         // Serialize this with the rest of the install-process message chain.  In the
17653         // restore-at-install case, this Runnable will necessarily run before the
17654         // POST_INSTALL message is processed, so the contents of mRunningInstalls
17655         // are coherent.  In the non-restore case, the app has already completed install
17656         // and been launched through some other means, so it is not in a problematic
17657         // state for observers to see the FIRST_LAUNCH signal.
17658         mHandler.post(() -> {
17659             for (int i = 0; i < mRunningInstalls.size(); i++) {
17660                 final PostInstallData data = mRunningInstalls.valueAt(i);
17661                 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17662                     continue;
17663                 }
17664                 if (packageName.equals(data.res.pkg.getPackageName())) {
17665                     // right package; but is it for the right user?
17666                     for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
17667                         if (userId == data.res.newUsers[uIndex]) {
17668                             if (DEBUG_BACKUP) {
17669                                 Slog.i(TAG, "Package " + packageName
17670                                         + " being restored so deferring FIRST_LAUNCH");
17671                             }
17672                             return;
17673                         }
17674                     }
17675                 }
17676             }
17677             // didn't find it, so not being restored
17678             if (DEBUG_BACKUP) {
17679                 Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
17680             }
17681             final boolean isInstantApp = isInstantApp(packageName, userId);
17682             final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
17683             final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
17684             sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
17685         });
17686     }
17687 
sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds, int[] instantUserIds)17688     private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
17689             int[] userIds, int[] instantUserIds) {
17690         sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
17691                 installerPkg, null, userIds, instantUserIds, null /* broadcastAllowList */, null);
17692     }
17693 
17694     private abstract class HandlerParams {
17695         /** User handle for the user requesting the information or installation. */
17696         private final UserHandle mUser;
17697         String traceMethod;
17698         int traceCookie;
17699 
HandlerParams(UserHandle user)17700         HandlerParams(UserHandle user) {
17701             mUser = user;
17702         }
17703 
getUser()17704         UserHandle getUser() {
17705             return mUser;
17706         }
17707 
setTraceMethod(String traceMethod)17708         HandlerParams setTraceMethod(String traceMethod) {
17709             this.traceMethod = traceMethod;
17710             return this;
17711         }
17712 
setTraceCookie(int traceCookie)17713         HandlerParams setTraceCookie(int traceCookie) {
17714             this.traceCookie = traceCookie;
17715             return this;
17716         }
17717 
startCopy()17718         final void startCopy() {
17719             if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
17720             handleStartCopy();
17721             handleReturnCode();
17722         }
17723 
handleStartCopy()17724         abstract void handleStartCopy();
handleReturnCode()17725         abstract void handleReturnCode();
17726     }
17727 
17728     static class OriginInfo {
17729         /**
17730          * Location where install is coming from, before it has been
17731          * copied/renamed into place. This could be a single monolithic APK
17732          * file, or a cluster directory. This location may be untrusted.
17733          */
17734         final File file;
17735 
17736         /**
17737          * Flag indicating that {@link #file} has already been staged, meaning downstream users
17738          * don't need to defensively copy the contents.
17739          */
17740         final boolean staged;
17741 
17742         /**
17743          * Flag indicating that {@link #file} is an already installed app that is being moved.
17744          */
17745         final boolean existing;
17746 
17747         final String resolvedPath;
17748         final File resolvedFile;
17749 
fromNothing()17750         static OriginInfo fromNothing() {
17751             return new OriginInfo(null, false, false);
17752         }
17753 
fromUntrustedFile(File file)17754         static OriginInfo fromUntrustedFile(File file) {
17755             return new OriginInfo(file, false, false);
17756         }
17757 
fromExistingFile(File file)17758         static OriginInfo fromExistingFile(File file) {
17759             return new OriginInfo(file, false, true);
17760         }
17761 
fromStagedFile(File file)17762         static OriginInfo fromStagedFile(File file) {
17763             return new OriginInfo(file, true, false);
17764         }
17765 
OriginInfo(File file, boolean staged, boolean existing)17766         private OriginInfo(File file, boolean staged, boolean existing) {
17767             this.file = file;
17768             this.staged = staged;
17769             this.existing = existing;
17770 
17771             if (file != null) {
17772                 resolvedPath = file.getAbsolutePath();
17773                 resolvedFile = file;
17774             } else {
17775                 resolvedPath = null;
17776                 resolvedFile = null;
17777             }
17778         }
17779     }
17780 
17781     static class MoveInfo {
17782         final int moveId;
17783         final String fromUuid;
17784         final String toUuid;
17785         final String packageName;
17786         final int appId;
17787         final String seinfo;
17788         final int targetSdkVersion;
17789         final String fromCodePath;
17790 
MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, int appId, String seinfo, int targetSdkVersion, String fromCodePath)17791         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
17792                 int appId, String seinfo, int targetSdkVersion,
17793                 String fromCodePath) {
17794             this.moveId = moveId;
17795             this.fromUuid = fromUuid;
17796             this.toUuid = toUuid;
17797             this.packageName = packageName;
17798             this.appId = appId;
17799             this.seinfo = seinfo;
17800             this.targetSdkVersion = targetSdkVersion;
17801             this.fromCodePath = fromCodePath;
17802         }
17803     }
17804 
17805     static class VerificationInfo {
17806         /** A constant used to indicate that a uid value is not present. */
17807         public static final int NO_UID = -1;
17808 
17809         /** URI referencing where the package was downloaded from. */
17810         final Uri originatingUri;
17811 
17812         /** HTTP referrer URI associated with the originatingURI. */
17813         final Uri referrer;
17814 
17815         /** UID of the application that the install request originated from. */
17816         final int originatingUid;
17817 
17818         /** UID of application requesting the install */
17819         final int installerUid;
17820 
VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid)17821         VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
17822             this.originatingUri = originatingUri;
17823             this.referrer = referrer;
17824             this.originatingUid = originatingUid;
17825             this.installerUid = installerUid;
17826         }
17827     }
17828 
17829     /**
17830      * Container for a multi-package install which refers to all install sessions and args being
17831      * committed together.
17832      */
17833     class MultiPackageInstallParams extends HandlerParams {
17834         private final List<InstallParams> mChildParams;
17835         private final Map<InstallArgs, Integer> mCurrentState;
17836 
MultiPackageInstallParams(InstallParams parent, List<InstallParams> childParams)17837         MultiPackageInstallParams(InstallParams parent, List<InstallParams> childParams)
17838                 throws PackageManagerException {
17839             super(parent.getUser());
17840             if (childParams.size() == 0) {
17841                 throw new PackageManagerException("No child sessions found!");
17842             }
17843             mChildParams = childParams;
17844             for (int i = 0; i < childParams.size(); i++) {
17845                 final InstallParams childParam = childParams.get(i);
17846                 childParam.mParentInstallParams = this;
17847             }
17848             this.mCurrentState = new ArrayMap<>(mChildParams.size());
17849         }
17850 
17851         @Override
handleStartCopy()17852         void handleStartCopy() {
17853             for (InstallParams params : mChildParams) {
17854                 params.handleStartCopy();
17855             }
17856         }
17857 
17858         @Override
handleReturnCode()17859         void handleReturnCode() {
17860             for (InstallParams params : mChildParams) {
17861                 params.handleReturnCode();
17862             }
17863         }
17864 
tryProcessInstallRequest(InstallArgs args, int currentStatus)17865         void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
17866             mCurrentState.put(args, currentStatus);
17867             if (mCurrentState.size() != mChildParams.size()) {
17868                 return;
17869             }
17870             int completeStatus = PackageManager.INSTALL_SUCCEEDED;
17871             for (Integer status : mCurrentState.values()) {
17872                 if (status == PackageManager.INSTALL_UNKNOWN) {
17873                     return;
17874                 } else if (status != PackageManager.INSTALL_SUCCEEDED) {
17875                     completeStatus = status;
17876                     break;
17877                 }
17878             }
17879             final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
17880             for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
17881                 installRequests.add(new InstallRequest(entry.getKey(),
17882                         createPackageInstalledInfo(completeStatus)));
17883             }
17884             processInstallRequestsAsync(
17885                     completeStatus == PackageManager.INSTALL_SUCCEEDED,
17886                     installRequests);
17887         }
17888     }
17889 
17890     class InstallParams extends HandlerParams {
17891         final OriginInfo origin;
17892         final MoveInfo move;
17893         final IPackageInstallObserver2 observer;
17894         int installFlags;
17895         @NonNull final InstallSource installSource;
17896         final String volumeUuid;
17897         int mRet;
17898         final String packageAbiOverride;
17899         final String[] grantedRuntimePermissions;
17900         final List<String> whitelistedRestrictedPermissions;
17901         final int autoRevokePermissionsMode;
17902         final PackageParser.SigningDetails signingDetails;
17903         final int installReason;
17904         final int mInstallScenario;
17905         @Nullable MultiPackageInstallParams mParentInstallParams;
17906         final boolean forceQueryableOverride;
17907         final int mDataLoaderType;
17908         final long requiredInstalledVersionCode;
17909         final PackageLite mPackageLite;
17910 
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, InstallSource installSource, String volumeUuid, UserHandle user, String packageAbiOverride, PackageLite packageLite)17911         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
17912                 int installFlags, InstallSource installSource, String volumeUuid,
17913                 UserHandle user, String packageAbiOverride, PackageLite packageLite) {
17914             super(user);
17915             this.origin = origin;
17916             this.move = move;
17917             this.observer = observer;
17918             this.installFlags = installFlags;
17919             this.installSource = Preconditions.checkNotNull(installSource);
17920             this.volumeUuid = volumeUuid;
17921             this.packageAbiOverride = packageAbiOverride;
17922 
17923             this.grantedRuntimePermissions = null;
17924             this.whitelistedRestrictedPermissions = null;
17925             this.autoRevokePermissionsMode = MODE_DEFAULT;
17926             this.signingDetails = PackageParser.SigningDetails.UNKNOWN;
17927             this.installReason = PackageManager.INSTALL_REASON_UNKNOWN;
17928             this.mInstallScenario = PackageManager.INSTALL_SCENARIO_DEFAULT;
17929             this.forceQueryableOverride = false;
17930             this.mDataLoaderType = DataLoaderType.NONE;
17931             this.requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST;
17932             this.mPackageLite = packageLite;
17933         }
17934 
InstallParams(File stagedDir, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, InstallSource installSource, UserHandle user, SigningDetails signingDetails, int installerUid, PackageLite packageLite)17935         InstallParams(File stagedDir, IPackageInstallObserver2 observer,
17936                 PackageInstaller.SessionParams sessionParams, InstallSource installSource,
17937                 UserHandle user, SigningDetails signingDetails, int installerUid,
17938                 PackageLite packageLite) {
17939             super(user);
17940             origin = OriginInfo.fromStagedFile(stagedDir);
17941             move = null;
17942             installReason = fixUpInstallReason(
17943                     installSource.installerPackageName, installerUid, sessionParams.installReason);
17944             mInstallScenario = sessionParams.installScenario;
17945             this.observer = observer;
17946             installFlags = sessionParams.installFlags;
17947             this.installSource = installSource;
17948             volumeUuid = sessionParams.volumeUuid;
17949             packageAbiOverride = sessionParams.abiOverride;
17950             grantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
17951             whitelistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
17952             autoRevokePermissionsMode = sessionParams.autoRevokePermissionsMode;
17953             this.signingDetails = signingDetails;
17954             forceQueryableOverride = sessionParams.forceQueryableOverride;
17955             mDataLoaderType = (sessionParams.dataLoaderParams != null)
17956                     ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
17957             requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
17958             mPackageLite = packageLite;
17959         }
17960 
17961         @Override
toString()17962         public String toString() {
17963             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
17964                     + " file=" + origin.file + "}";
17965         }
17966 
installLocationPolicy(PackageInfoLite pkgLite)17967         private int installLocationPolicy(PackageInfoLite pkgLite) {
17968             String packageName = pkgLite.packageName;
17969             int installLocation = pkgLite.installLocation;
17970             // reader
17971             synchronized (mLock) {
17972                 // Currently installed package which the new package is attempting to replace or
17973                 // null if no such package is installed.
17974                 AndroidPackage installedPkg = mPackages.get(packageName);
17975 
17976                 if (installedPkg != null) {
17977                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17978                         // Check for updated system application.
17979                         if (installedPkg.isSystem()) {
17980                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
17981                         } else {
17982                             // If current upgrade specifies particular preference
17983                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
17984                                 // Application explicitly specified internal.
17985                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
17986                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
17987                                 // App explictly prefers external. Let policy decide
17988                             } else {
17989                                 // Prefer previous location
17990                                 if (installedPkg.isExternalStorage()) {
17991                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
17992                                 }
17993                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
17994                             }
17995                         }
17996                     } else {
17997                         // Invalid install. Return error code
17998                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
17999                     }
18000                 }
18001             }
18002             return pkgLite.recommendedInstallLocation;
18003         }
18004 
18005         /**
18006          * Override install location based on default policy if needed.
18007          *
18008          * Only {@link #installFlags} may mutate in this method.
18009          *
18010          * Only {@link PackageManager#INSTALL_INTERNAL} flag may mutate in
18011          * {@link #installFlags}
18012          */
overrideInstallLocation(PackageInfoLite pkgLite)18013         private int overrideInstallLocation(PackageInfoLite pkgLite) {
18014             final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
18015             if (DEBUG_INSTANT && ephemeral) {
18016                 Slog.v(TAG, "pkgLite for install: " + pkgLite);
18017             }
18018 
18019             if (origin.staged) {
18020                 // If we're already staged, we've firmly committed to an install location
18021                 if (origin.file != null) {
18022                     installFlags |= PackageManager.INSTALL_INTERNAL;
18023                 } else {
18024                     throw new IllegalStateException("Invalid stage location");
18025                 }
18026             } else if (pkgLite.recommendedInstallLocation
18027                     == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
18028                 /*
18029                  * If we are not staged and have too little free space, try to free cache
18030                  * before giving up.
18031                  */
18032                 // TODO: focus freeing disk space on the target device
18033                 final StorageManager storage = StorageManager.from(mContext);
18034                 final long lowThreshold = storage.getStorageLowBytes(
18035                         Environment.getDataDirectory());
18036 
18037                 final long sizeBytes = PackageManagerServiceUtils.calculateInstalledSize(
18038                         origin.resolvedPath, packageAbiOverride);
18039                 if (sizeBytes >= 0) {
18040                     try {
18041                         mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
18042                         pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
18043                                 mPackageLite, origin.resolvedPath, installFlags,
18044                                 packageAbiOverride);
18045                     } catch (InstallerException e) {
18046                         Slog.w(TAG, "Failed to free cache", e);
18047                     }
18048                 }
18049 
18050                 /*
18051                  * The cache free must have deleted the file we downloaded to install.
18052                  *
18053                  * TODO: fix the "freeCache" call to not delete the file we care about.
18054                  */
18055                 if (pkgLite.recommendedInstallLocation
18056                         == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
18057                     pkgLite.recommendedInstallLocation
18058                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
18059                 }
18060             }
18061 
18062             int ret = INSTALL_SUCCEEDED;
18063             int loc = pkgLite.recommendedInstallLocation;
18064             if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
18065                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
18066             } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
18067                 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
18068             } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
18069                 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
18070             } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
18071                 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
18072             } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
18073                 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
18074             } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
18075                 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
18076             } else {
18077                 // Override with defaults if needed.
18078                 loc = installLocationPolicy(pkgLite);
18079 
18080                 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
18081 
18082                 if (!onInt) {
18083                     // Override install location with flags
18084                     if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
18085                         // Set the flag to install on external media.
18086                         installFlags &= ~PackageManager.INSTALL_INTERNAL;
18087                     } else {
18088                         // Make sure the flag for installing on external
18089                         // media is unset
18090                         installFlags |= PackageManager.INSTALL_INTERNAL;
18091                     }
18092                 }
18093             }
18094             return ret;
18095         }
18096 
18097         /*
18098          * Invoke remote method to get package information and install
18099          * location values. Override install location based on default
18100          * policy if needed and then create install arguments based
18101          * on the install location.
18102          */
handleStartCopy()18103         public void handleStartCopy() {
18104             if ((installFlags & PackageManager.INSTALL_APEX) != 0) {
18105                 mRet = INSTALL_SUCCEEDED;
18106                 return;
18107             }
18108             PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
18109                     mPackageLite, origin.resolvedPath, installFlags, packageAbiOverride);
18110 
18111             // For staged session, there is a delay between its verification and install. Device
18112             // state can change within this delay and hence we need to re-verify certain conditions.
18113             boolean isStaged = (installFlags & INSTALL_STAGED) != 0;
18114             if (isStaged) {
18115                 mRet = verifyReplacingVersionCode(
18116                         pkgLite, requiredInstalledVersionCode, installFlags);
18117                 if (mRet != INSTALL_SUCCEEDED) {
18118                     return;
18119                 }
18120             }
18121 
18122             mRet = overrideInstallLocation(pkgLite);
18123         }
18124 
18125         @Override
handleReturnCode()18126         void handleReturnCode() {
18127             processPendingInstall();
18128         }
18129 
processPendingInstall()18130         private void processPendingInstall() {
18131             InstallArgs args = createInstallArgs(this);
18132             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
18133                 mRet = args.copyApk();
18134             }
18135             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
18136                 F2fsUtils.releaseCompressedBlocks(
18137                         mContext.getContentResolver(), new File(args.getCodePath()));
18138             }
18139             if (mParentInstallParams != null) {
18140                 mParentInstallParams.tryProcessInstallRequest(args, mRet);
18141             } else {
18142                 PackageInstalledInfo res = createPackageInstalledInfo(mRet);
18143                 processInstallRequestsAsync(
18144                         res.returnCode == PackageManager.INSTALL_SUCCEEDED,
18145                         Collections.singletonList(new InstallRequest(args, res)));
18146             }
18147         }
18148     }
18149 
18150     /**
18151      * Container for a multi-package install which refers to all install sessions and args being
18152      * committed together.
18153      */
18154     class MultiPackageVerificationParams extends HandlerParams {
18155         private final IPackageInstallObserver2 mObserver;
18156         private final List<VerificationParams> mChildParams;
18157         private final Map<VerificationParams, Integer> mVerificationState;
18158 
MultiPackageVerificationParams( VerificationParams parent, List<VerificationParams> children)18159         MultiPackageVerificationParams(
18160                 VerificationParams parent,
18161                 List<VerificationParams> children)
18162                 throws PackageManagerException {
18163             super(parent.getUser());
18164             if (children.size() == 0) {
18165                 throw new PackageManagerException("No child sessions found!");
18166             }
18167             mChildParams = children;
18168             // Provide every child with reference to this object as parent
18169             for (int i = 0; i < children.size(); i++) {
18170                 final VerificationParams childParams = children.get(i);
18171                 childParams.mParentVerificationParams = this;
18172             }
18173             this.mVerificationState = new ArrayMap<>(mChildParams.size());
18174             mObserver = parent.observer;
18175         }
18176 
18177         @Override
handleStartCopy()18178         void handleStartCopy() {
18179             for (VerificationParams params : mChildParams) {
18180                 params.handleStartCopy();
18181             }
18182         }
18183 
18184         @Override
handleReturnCode()18185         void handleReturnCode() {
18186             for (VerificationParams params : mChildParams) {
18187                 params.handleReturnCode();
18188             }
18189         }
18190 
trySendVerificationCompleteNotification(VerificationParams child, int currentStatus)18191         void trySendVerificationCompleteNotification(VerificationParams child, int currentStatus) {
18192             mVerificationState.put(child, currentStatus);
18193             if (mVerificationState.size() != mChildParams.size()) {
18194                 return;
18195             }
18196             int completeStatus = PackageManager.INSTALL_SUCCEEDED;
18197             for (Integer status : mVerificationState.values()) {
18198                 if (status == PackageManager.INSTALL_UNKNOWN) {
18199                     return;
18200                 } else if (status != PackageManager.INSTALL_SUCCEEDED) {
18201                     completeStatus = status;
18202                     break;
18203                 }
18204             }
18205             try {
18206                 mObserver.onPackageInstalled(null, completeStatus,
18207                         "Package Verification Result", new Bundle());
18208             } catch (RemoteException e) {
18209                 Slog.i(TAG, "Observer no longer exists.");
18210             }
18211         }
18212     }
18213 
18214     class VerificationParams extends HandlerParams {
18215         final OriginInfo origin;
18216         final IPackageInstallObserver2 observer;
18217         final int installFlags;
18218         @NonNull final InstallSource installSource;
18219         final String packageAbiOverride;
18220         final VerificationInfo verificationInfo;
18221         final PackageParser.SigningDetails signingDetails;
18222         @Nullable MultiPackageVerificationParams mParentVerificationParams;
18223         final long requiredInstalledVersionCode;
18224         final int mDataLoaderType;
18225         final int mSessionId;
18226 
18227         private boolean mWaitForVerificationToComplete;
18228         private boolean mWaitForIntegrityVerificationToComplete;
18229         private boolean mWaitForEnableRollbackToComplete;
18230         private int mRet;
18231 
18232         final PackageLite mPackageLite;
18233 
VerificationParams(UserHandle user, File stagedDir, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, InstallSource installSource, int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite)18234         VerificationParams(UserHandle user, File stagedDir, IPackageInstallObserver2 observer,
18235                 PackageInstaller.SessionParams sessionParams, InstallSource installSource,
18236                 int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite) {
18237             super(user);
18238             origin = OriginInfo.fromStagedFile(stagedDir);
18239             this.observer = observer;
18240             installFlags = sessionParams.installFlags;
18241             this.installSource = installSource;
18242             packageAbiOverride = sessionParams.abiOverride;
18243             verificationInfo = new VerificationInfo(
18244                     sessionParams.originatingUri,
18245                     sessionParams.referrerUri,
18246                     sessionParams.originatingUid,
18247                     installerUid
18248             );
18249             this.signingDetails = signingDetails;
18250             requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
18251             mDataLoaderType = (sessionParams.dataLoaderParams != null)
18252                     ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
18253             mSessionId = sessionId;
18254             mPackageLite = lite;
18255         }
18256 
18257         @Override
toString()18258         public String toString() {
18259             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
18260                     + " file=" + origin.file + "}";
18261         }
18262 
handleStartCopy()18263         public void handleStartCopy() {
18264             if ((installFlags & PackageManager.INSTALL_APEX) != 0) {
18265                 // Apex packages get verified in StagingManager currently.
18266                 // TODO(b/136257624): Move apex verification logic out of StagingManager
18267                 mRet = INSTALL_SUCCEEDED;
18268                 return;
18269             }
18270 
18271             PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
18272                     mPackageLite, origin.resolvedPath, installFlags, packageAbiOverride);
18273 
18274             mRet = verifyReplacingVersionCode(pkgLite, requiredInstalledVersionCode, installFlags);
18275             if (mRet != INSTALL_SUCCEEDED) {
18276                 return;
18277             }
18278 
18279             // Perform package verification and enable rollback (unless we are simply moving the
18280             // package).
18281             if (!origin.existing) {
18282                 sendApkVerificationRequest(pkgLite);
18283                 if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
18284                     sendEnableRollbackRequest();
18285                 }
18286             }
18287         }
18288 
sendApkVerificationRequest(PackageInfoLite pkgLite)18289         void sendApkVerificationRequest(PackageInfoLite pkgLite) {
18290             final int verificationId = mPendingVerificationToken++;
18291 
18292             PackageVerificationState verificationState =
18293                     new PackageVerificationState(this);
18294             mPendingVerification.append(verificationId, verificationState);
18295 
18296             sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
18297             mRet = sendPackageVerificationRequest(
18298                     verificationId, pkgLite, verificationState);
18299 
18300             // If both verifications are skipped, we should remove the state.
18301             if (verificationState.areAllVerificationsComplete()) {
18302                 mPendingVerification.remove(verificationId);
18303             }
18304         }
18305 
sendEnableRollbackRequest()18306         void sendEnableRollbackRequest() {
18307             final int enableRollbackToken = mPendingEnableRollbackToken++;
18308             Trace.asyncTraceBegin(
18309                     TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
18310             mPendingEnableRollback.append(enableRollbackToken, this);
18311 
18312             Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
18313             enableRollbackIntent.putExtra(
18314                     PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
18315                     enableRollbackToken);
18316             enableRollbackIntent.putExtra(
18317                     PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID,
18318                     mSessionId);
18319             enableRollbackIntent.setType(PACKAGE_MIME_TYPE);
18320             enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
18321 
18322             // Allow the broadcast to be sent before boot complete.
18323             // This is needed when committing the apk part of a staged
18324             // session in early boot. The rollback manager registers
18325             // its receiver early enough during the boot process that
18326             // it will not miss the broadcast.
18327             enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
18328 
18329             mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, UserHandle.SYSTEM,
18330                     android.Manifest.permission.PACKAGE_ROLLBACK_AGENT,
18331                     new BroadcastReceiver() {
18332                         @Override
18333                         public void onReceive(Context context, Intent intent) {
18334                             // the duration to wait for rollback to be enabled, in millis
18335                             long rollbackTimeout = DeviceConfig.getLong(
18336                                     DeviceConfig.NAMESPACE_ROLLBACK,
18337                                     PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
18338                                     DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS);
18339                             if (rollbackTimeout < 0) {
18340                                 rollbackTimeout = DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS;
18341                             }
18342                             final Message msg = mHandler.obtainMessage(
18343                                     ENABLE_ROLLBACK_TIMEOUT);
18344                             msg.arg1 = enableRollbackToken;
18345                             msg.arg2 = mSessionId;
18346                             mHandler.sendMessageDelayed(msg, rollbackTimeout);
18347                         }
18348                     }, null, 0, null, null);
18349 
18350             mWaitForEnableRollbackToComplete = true;
18351         }
18352 
18353         /**
18354          * Send a request to check the integrity of the package.
18355          */
sendIntegrityVerificationRequest( int verificationId, PackageInfoLite pkgLite, PackageVerificationState verificationState)18356         void sendIntegrityVerificationRequest(
18357                 int verificationId,
18358                 PackageInfoLite pkgLite,
18359                 PackageVerificationState verificationState) {
18360             if (!isIntegrityVerificationEnabled()) {
18361                 // Consider the integrity check as passed.
18362                 verificationState.setIntegrityVerificationResult(
18363                         PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
18364                 return;
18365             }
18366 
18367             final Intent integrityVerification =
18368                     new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
18369 
18370             integrityVerification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
18371                     PACKAGE_MIME_TYPE);
18372 
18373             final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
18374                     | Intent.FLAG_RECEIVER_REGISTERED_ONLY
18375                     | Intent.FLAG_RECEIVER_FOREGROUND;
18376             integrityVerification.addFlags(flags);
18377 
18378             integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
18379             integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
18380             integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
18381             integrityVerification.putExtra(EXTRA_LONG_VERSION_CODE, pkgLite.getLongVersionCode());
18382             populateInstallerExtras(integrityVerification);
18383 
18384             // send to integrity component only.
18385             integrityVerification.setPackage("android");
18386 
18387             final BroadcastOptions options = BroadcastOptions.makeBasic();
18388 
18389             mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
18390                     /* receiverPermission= */ null,
18391                     /* appOp= */ AppOpsManager.OP_NONE,
18392                     /* options= */ options.toBundle(),
18393                     new BroadcastReceiver() {
18394                         @Override
18395                         public void onReceive(Context context, Intent intent) {
18396                             final Message msg =
18397                                     mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
18398                             msg.arg1 = verificationId;
18399                             mHandler.sendMessageDelayed(msg, getIntegrityVerificationTimeout());
18400                         }
18401                     }, /* scheduler= */ null,
18402                     /* initialCode= */ 0,
18403                     /* initialData= */ null,
18404                     /* initialExtras= */ null);
18405 
18406             Trace.asyncTraceBegin(
18407                     TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);
18408 
18409             // stop the copy until verification succeeds.
18410             mWaitForIntegrityVerificationToComplete = true;
18411         }
18412 
18413         /**
18414          * Send a request to verifier(s) to verify the package if necessary, and return
18415          * {@link PackageManager#INSTALL_SUCCEEDED} if succeeded.
18416          */
sendPackageVerificationRequest( int verificationId, PackageInfoLite pkgLite, PackageVerificationState verificationState)18417         int sendPackageVerificationRequest(
18418                 int verificationId,
18419                 PackageInfoLite pkgLite,
18420                 PackageVerificationState verificationState) {
18421             int ret = INSTALL_SUCCEEDED;
18422 
18423             // TODO: http://b/22976637
18424             // Apps installed for "all" users use the device owner to verify the app
18425             UserHandle verifierUser = getUser();
18426             if (verifierUser == UserHandle.ALL) {
18427                 verifierUser = UserHandle.SYSTEM;
18428             }
18429 
18430             /*
18431              * Determine if we have any installed package verifiers. If we
18432              * do, then we'll defer to them to verify the packages.
18433              */
18434             final int requiredUid = mRequiredVerifierPackage == null ? -1
18435                     : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18436                             verifierUser.getIdentifier());
18437             verificationState.setRequiredVerifierUid(requiredUid);
18438             final int installerUid =
18439                     verificationInfo == null ? -1 : verificationInfo.installerUid;
18440             final boolean isVerificationEnabled = isVerificationEnabled(
18441                     pkgLite, verifierUser.getIdentifier(), installFlags, installerUid);
18442             final boolean isV4Signed =
18443                     (signingDetails.signatureSchemeVersion == SIGNING_BLOCK_V4);
18444             final boolean isIncrementalInstall =
18445                     (mDataLoaderType == DataLoaderType.INCREMENTAL);
18446             // NOTE: We purposefully skip verification for only incremental installs when there's
18447             // a v4 signature block. Otherwise, proceed with verification as usual.
18448             if (!origin.existing
18449                     && isVerificationEnabled
18450                     && (!isIncrementalInstall || !isV4Signed)) {
18451                 final Intent verification = new Intent(
18452                         Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
18453                 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18454                 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
18455                         PACKAGE_MIME_TYPE);
18456                 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
18457 
18458                 // Query all live verifiers based on current user state
18459                 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
18460                         PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
18461                         false /*allowDynamicSplits*/);
18462 
18463                 if (DEBUG_VERIFY) {
18464                     Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
18465                             + verification.toString() + " with " + pkgLite.verifiers.length
18466                             + " optional verifiers");
18467                 }
18468 
18469                 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
18470 
18471                 verification.putExtra(
18472                         PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, installFlags);
18473 
18474                 verification.putExtra(
18475                         PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, pkgLite.packageName);
18476 
18477                 verification.putExtra(
18478                         PackageManager.EXTRA_VERIFICATION_VERSION_CODE, pkgLite.versionCode);
18479 
18480                 verification.putExtra(
18481                         PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
18482                         pkgLite.getLongVersionCode());
18483 
18484                 populateInstallerExtras(verification);
18485 
18486                 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
18487                         receivers, verificationState);
18488 
18489                 DeviceIdleInternal idleController =
18490                         mInjector.getLocalService(DeviceIdleInternal.class);
18491                 final long idleDuration = getVerificationTimeout();
18492                 final BroadcastOptions options = BroadcastOptions.makeBasic();
18493                 options.setTemporaryAppAllowlist(idleDuration,
18494                         TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
18495                         REASON_PACKAGE_VERIFIER, "");
18496 
18497                 /*
18498                  * If any sufficient verifiers were listed in the package
18499                  * manifest, attempt to ask them.
18500                  */
18501                 if (sufficientVerifiers != null) {
18502                     final int n = sufficientVerifiers.size();
18503                     if (n == 0) {
18504                         Slog.i(TAG, "Additional verifiers required, but none installed.");
18505                         ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
18506                     } else {
18507                         for (int i = 0; i < n; i++) {
18508                             final ComponentName verifierComponent = sufficientVerifiers.get(i);
18509                             idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
18510                                     verifierComponent.getPackageName(), idleDuration,
18511                                     verifierUser.getIdentifier(), false,
18512                                     REASON_PACKAGE_VERIFIER,"package verifier");
18513 
18514                             final Intent sufficientIntent = new Intent(verification);
18515                             sufficientIntent.setComponent(verifierComponent);
18516                             mContext.sendBroadcastAsUser(sufficientIntent, verifierUser,
18517                                     /* receiverPermission= */ null,
18518                                     options.toBundle());
18519                         }
18520                     }
18521                 }
18522 
18523                 if (mRequiredVerifierPackage != null) {
18524                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
18525                             mRequiredVerifierPackage, receivers);
18526                     /*
18527                      * Send the intent to the required verification agent,
18528                      * but only start the verification timeout after the
18529                      * target BroadcastReceivers have run.
18530                      */
18531                     verification.setComponent(requiredVerifierComponent);
18532                     idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
18533                             mRequiredVerifierPackage, idleDuration,
18534                             verifierUser.getIdentifier(), false,
18535                             REASON_PACKAGE_VERIFIER, "package verifier");
18536                     mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
18537                             android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
18538                             /* appOp= */ AppOpsManager.OP_NONE,
18539                             /* options= */ options.toBundle(),
18540                             new BroadcastReceiver() {
18541                                 @Override
18542                                 public void onReceive(Context context, Intent intent) {
18543                                     final Message msg = mHandler
18544                                             .obtainMessage(CHECK_PENDING_VERIFICATION);
18545                                     msg.arg1 = verificationId;
18546                                     mHandler.sendMessageDelayed(msg, getVerificationTimeout());
18547                                 }
18548                             }, null, 0, null, null);
18549 
18550                     Trace.asyncTraceBegin(
18551                             TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
18552 
18553                     /*
18554                      * We don't want the copy to proceed until verification
18555                      * succeeds.
18556                      */
18557                     mWaitForVerificationToComplete = true;
18558                 }
18559             } else {
18560                 verificationState.setVerifierResponse(
18561                         requiredUid, PackageManager.VERIFICATION_ALLOW);
18562             }
18563             return ret;
18564         }
18565 
populateInstallerExtras(Intent intent)18566         void populateInstallerExtras(Intent intent) {
18567             intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
18568                     installSource.initiatingPackageName);
18569 
18570             if (verificationInfo != null) {
18571                 if (verificationInfo.originatingUri != null) {
18572                     intent.putExtra(Intent.EXTRA_ORIGINATING_URI,
18573                             verificationInfo.originatingUri);
18574                 }
18575                 if (verificationInfo.referrer != null) {
18576                     intent.putExtra(Intent.EXTRA_REFERRER,
18577                             verificationInfo.referrer);
18578                 }
18579                 if (verificationInfo.originatingUid >= 0) {
18580                     intent.putExtra(Intent.EXTRA_ORIGINATING_UID,
18581                             verificationInfo.originatingUid);
18582                 }
18583                 if (verificationInfo.installerUid >= 0) {
18584                     intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
18585                             verificationInfo.installerUid);
18586                 }
18587             }
18588         }
18589 
setReturnCode(int ret)18590         void setReturnCode(int ret) {
18591             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
18592                 // Only update mRet if it was previously INSTALL_SUCCEEDED to
18593                 // ensure we do not overwrite any previous failure results.
18594                 mRet = ret;
18595             }
18596         }
18597 
handleVerificationFinished()18598         void handleVerificationFinished() {
18599             mWaitForVerificationToComplete = false;
18600             handleReturnCode();
18601         }
18602 
handleIntegrityVerificationFinished()18603         void handleIntegrityVerificationFinished() {
18604             mWaitForIntegrityVerificationToComplete = false;
18605             handleReturnCode();
18606         }
18607 
18608 
handleRollbackEnabled()18609         void handleRollbackEnabled() {
18610             // TODO(ruhler) b/112431924: Consider halting the install if we
18611             // couldn't enable rollback.
18612             mWaitForEnableRollbackToComplete = false;
18613             handleReturnCode();
18614         }
18615 
18616         @Override
handleReturnCode()18617         void handleReturnCode() {
18618             if (mWaitForVerificationToComplete || mWaitForIntegrityVerificationToComplete
18619                     || mWaitForEnableRollbackToComplete) {
18620                 return;
18621             }
18622             sendVerificationCompleteNotification();
18623         }
18624 
sendVerificationCompleteNotification()18625         private void sendVerificationCompleteNotification() {
18626             if (mParentVerificationParams != null) {
18627                 mParentVerificationParams.trySendVerificationCompleteNotification(this, mRet);
18628             } else {
18629                 try {
18630                     observer.onPackageInstalled(null, mRet, "Package Verification Result",
18631                             new Bundle());
18632                 } catch (RemoteException e) {
18633                     Slog.i(TAG, "Observer no longer exists.");
18634                 }
18635             }
18636         }
18637     }
18638 
createInstallArgs(InstallParams params)18639     private InstallArgs createInstallArgs(InstallParams params) {
18640         if (params.move != null) {
18641             return new MoveInstallArgs(params);
18642         } else {
18643             return new FileInstallArgs(params);
18644         }
18645     }
18646 
18647     /**
18648      * Create args that describe an existing installed package. Typically used
18649      * when cleaning up old installs, or used as a move source.
18650      */
createInstallArgsForExisting(String codePath, String[] instructionSets)18651     private InstallArgs createInstallArgsForExisting(String codePath, String[] instructionSets) {
18652         return new FileInstallArgs(codePath, instructionSets);
18653     }
18654 
18655     static abstract class InstallArgs {
18656         /** @see InstallParams#origin */
18657         final OriginInfo origin;
18658         /** @see InstallParams#move */
18659         final MoveInfo move;
18660 
18661         final IPackageInstallObserver2 observer;
18662         // Always refers to PackageManager flags only
18663         final int installFlags;
18664         @NonNull final InstallSource installSource;
18665         final String volumeUuid;
18666         final UserHandle user;
18667         final String abiOverride;
18668         final String[] installGrantPermissions;
18669         final List<String> whitelistedRestrictedPermissions;
18670         final int autoRevokePermissionsMode;
18671         /** If non-null, drop an async trace when the install completes */
18672         final String traceMethod;
18673         final int traceCookie;
18674         final PackageParser.SigningDetails signingDetails;
18675         final int installReason;
18676         final int mInstallScenario;
18677         final boolean forceQueryableOverride;
18678         final int mDataLoaderType;
18679 
18680         // The list of instruction sets supported by this app. This is currently
18681         // only used during the rmdex() phase to clean up resources. We can get rid of this
18682         // if we move dex files under the common app path.
18683         /* nullable */ String[] instructionSets;
18684 
InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, InstallSource installSource, String volumeUuid, UserHandle user, String[] instructionSets, String abiOverride, String[] installGrantPermissions, List<String> whitelistedRestrictedPermissions, int autoRevokePermissionsMode, String traceMethod, int traceCookie, SigningDetails signingDetails, int installReason, int installScenario, boolean forceQueryableOverride, int dataLoaderType)18685         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
18686                 int installFlags, InstallSource installSource, String volumeUuid,
18687                 UserHandle user, String[] instructionSets,
18688                 String abiOverride, String[] installGrantPermissions,
18689                 List<String> whitelistedRestrictedPermissions,
18690                 int autoRevokePermissionsMode,
18691                 String traceMethod, int traceCookie, SigningDetails signingDetails,
18692                 int installReason, int installScenario, boolean forceQueryableOverride,
18693                 int dataLoaderType) {
18694             this.origin = origin;
18695             this.move = move;
18696             this.installFlags = installFlags;
18697             this.observer = observer;
18698             this.installSource = Preconditions.checkNotNull(installSource);
18699             this.volumeUuid = volumeUuid;
18700             this.user = user;
18701             this.instructionSets = instructionSets;
18702             this.abiOverride = abiOverride;
18703             this.installGrantPermissions = installGrantPermissions;
18704             this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
18705             this.autoRevokePermissionsMode = autoRevokePermissionsMode;
18706             this.traceMethod = traceMethod;
18707             this.traceCookie = traceCookie;
18708             this.signingDetails = signingDetails;
18709             this.installReason = installReason;
18710             this.mInstallScenario = installScenario;
18711             this.forceQueryableOverride = forceQueryableOverride;
18712             this.mDataLoaderType = dataLoaderType;
18713         }
18714 
18715         /** New install */
InstallArgs(InstallParams params)18716         InstallArgs(InstallParams params) {
18717             this(params.origin, params.move, params.observer, params.installFlags,
18718                     params.installSource, params.volumeUuid,
18719                     params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
18720                     params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
18721                     params.autoRevokePermissionsMode,
18722                     params.traceMethod, params.traceCookie, params.signingDetails,
18723                     params.installReason, params.mInstallScenario, params.forceQueryableOverride,
18724                     params.mDataLoaderType);
18725         }
18726 
copyApk()18727         abstract int copyApk();
doPreInstall(int status)18728         abstract int doPreInstall(int status);
18729 
18730         /**
18731          * Rename package into final resting place. All paths on the given
18732          * scanned package should be updated to reflect the rename.
18733          */
doRename(int status, ParsedPackage parsedPackage)18734         abstract boolean doRename(int status, ParsedPackage parsedPackage);
doPostInstall(int status, int uid)18735         abstract int doPostInstall(int status, int uid);
18736 
18737         /** @see PackageSettingBase#getPath() */
getCodePath()18738         abstract String getCodePath();
18739 
18740         // Need installer lock especially for dex file removal.
cleanUpResourcesLI()18741         abstract void cleanUpResourcesLI();
doPostDeleteLI(boolean delete)18742         abstract boolean doPostDeleteLI(boolean delete);
18743 
18744         /**
18745          * Called before the source arguments are copied. This is used mostly
18746          * for MoveParams when it needs to read the source file to put it in the
18747          * destination.
18748          */
doPreCopy()18749         int doPreCopy() {
18750             return PackageManager.INSTALL_SUCCEEDED;
18751         }
18752 
18753         /**
18754          * Called after the source arguments are copied. This is used mostly for
18755          * MoveParams when it needs to read the source file to put it in the
18756          * destination.
18757          */
doPostCopy(int uid)18758         int doPostCopy(int uid) {
18759             return PackageManager.INSTALL_SUCCEEDED;
18760         }
18761 
isEphemeral()18762         protected boolean isEphemeral() {
18763             return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
18764         }
18765 
getUser()18766         UserHandle getUser() {
18767             return user;
18768         }
18769     }
18770 
removeDexFiles(List<String> allCodePaths, String[] instructionSets)18771     void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
18772         if (!allCodePaths.isEmpty()) {
18773             if (instructionSets == null) {
18774                 throw new IllegalStateException("instructionSet == null");
18775             }
18776             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
18777             for (String codePath : allCodePaths) {
18778                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
18779                     try {
18780                         mInstaller.rmdex(codePath, dexCodeInstructionSet);
18781                     } catch (InstallerException ignored) {
18782                     }
18783                 }
18784             }
18785         }
18786     }
18787 
18788     /**
18789      * Logic to handle installation of new applications, including copying
18790      * and renaming logic.
18791      */
18792     class FileInstallArgs extends InstallArgs {
18793         private File codeFile;
18794         private File resourceFile;
18795 
18796         // Example topology:
18797         // /data/app/com.example/base.apk
18798         // /data/app/com.example/split_foo.apk
18799         // /data/app/com.example/lib/arm/libfoo.so
18800         // /data/app/com.example/lib/arm64/libfoo.so
18801         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
18802 
18803         /** New install */
FileInstallArgs(InstallParams params)18804         FileInstallArgs(InstallParams params) {
18805             super(params);
18806         }
18807 
18808         /** Existing install */
FileInstallArgs(String codePath, String[] instructionSets)18809         FileInstallArgs(String codePath, String[] instructionSets) {
18810             super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
18811                     null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
18812                     PackageParser.SigningDetails.UNKNOWN,
18813                     PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.INSTALL_SCENARIO_DEFAULT,
18814                     false, DataLoaderType.NONE);
18815             this.codeFile = (codePath != null) ? new File(codePath) : null;
18816         }
18817 
copyApk()18818         int copyApk() {
18819             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
18820             try {
18821                 return doCopyApk();
18822             } finally {
18823                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18824             }
18825         }
18826 
doCopyApk()18827         private int doCopyApk() {
18828             if (origin.staged) {
18829                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
18830                 codeFile = origin.file;
18831                 return PackageManager.INSTALL_SUCCEEDED;
18832             }
18833 
18834             try {
18835                 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
18836                 final File tempDir =
18837                         mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
18838                 codeFile = tempDir;
18839             } catch (IOException e) {
18840                 Slog.w(TAG, "Failed to create copy file: " + e);
18841                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
18842             }
18843 
18844             int ret = PackageManagerServiceUtils.copyPackage(
18845                     origin.file.getAbsolutePath(), codeFile);
18846             if (ret != PackageManager.INSTALL_SUCCEEDED) {
18847                 Slog.e(TAG, "Failed to copy package");
18848                 return ret;
18849             }
18850 
18851             final boolean isIncremental = isIncrementalPath(codeFile.getAbsolutePath());
18852             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
18853             NativeLibraryHelper.Handle handle = null;
18854             try {
18855                 handle = NativeLibraryHelper.Handle.create(codeFile);
18856                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
18857                         abiOverride, isIncremental);
18858             } catch (IOException e) {
18859                 Slog.e(TAG, "Copying native libraries failed", e);
18860                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
18861             } finally {
18862                 IoUtils.closeQuietly(handle);
18863             }
18864 
18865             return ret;
18866         }
18867 
doPreInstall(int status)18868         int doPreInstall(int status) {
18869             if (status != PackageManager.INSTALL_SUCCEEDED) {
18870                 cleanUp();
18871             }
18872             return status;
18873         }
18874 
18875         @Override
doRename(int status, ParsedPackage parsedPackage)18876         boolean doRename(int status, ParsedPackage parsedPackage) {
18877             if (status != PackageManager.INSTALL_SUCCEEDED) {
18878                 cleanUp();
18879                 return false;
18880             }
18881 
18882             final File targetDir = resolveTargetDir();
18883             final File beforeCodeFile = codeFile;
18884             final File afterCodeFile = getNextCodePath(targetDir, parsedPackage.getPackageName());
18885 
18886             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
18887             final boolean onIncremental = mIncrementalManager != null
18888                     && isIncrementalPath(beforeCodeFile.getAbsolutePath());
18889             try {
18890                 makeDirRecursive(afterCodeFile.getParentFile(), 0775);
18891                 if (onIncremental) {
18892                     // Just link files here. The stage dir will be removed when the installation
18893                     // session is completed.
18894                     mIncrementalManager.linkCodePath(beforeCodeFile, afterCodeFile);
18895                 } else {
18896                     Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
18897                 }
18898             } catch (IOException | ErrnoException e) {
18899                 Slog.w(TAG, "Failed to rename", e);
18900                 return false;
18901             }
18902 
18903             if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
18904                 Slog.w(TAG, "Failed to restorecon");
18905                 return false;
18906             }
18907 
18908             // Reflect the rename internally
18909             codeFile = afterCodeFile;
18910 
18911             // Reflect the rename in scanned details
18912             try {
18913                 parsedPackage.setCodePath(afterCodeFile.getCanonicalPath());
18914             } catch (IOException e) {
18915                 Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
18916                 return false;
18917             }
18918             parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
18919                     afterCodeFile, parsedPackage.getBaseApkPath()));
18920             parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
18921                     afterCodeFile, parsedPackage.getSplitCodePaths()));
18922 
18923             return true;
18924         }
18925 
18926         // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged
18927         //  flow, we won't need this method anymore.
resolveTargetDir()18928         private File resolveTargetDir() {
18929             boolean isStagedInstall = (installFlags & INSTALL_STAGED) != 0;
18930             if (isStagedInstall) {
18931                 return Environment.getDataAppDirectory(null);
18932             } else {
18933                 return codeFile.getParentFile();
18934             }
18935         }
18936 
doPostInstall(int status, int uid)18937         int doPostInstall(int status, int uid) {
18938             if (status != PackageManager.INSTALL_SUCCEEDED) {
18939                 cleanUp();
18940             }
18941             return status;
18942         }
18943 
18944         @Override
getCodePath()18945         String getCodePath() {
18946             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
18947         }
18948 
cleanUp()18949         private boolean cleanUp() {
18950             if (codeFile == null || !codeFile.exists()) {
18951                 return false;
18952             }
18953             removeCodePathLI(codeFile);
18954             return true;
18955         }
18956 
cleanUpResourcesLI()18957         void cleanUpResourcesLI() {
18958             // Try enumerating all code paths before deleting
18959             List<String> allCodePaths = Collections.EMPTY_LIST;
18960             if (codeFile != null && codeFile.exists()) {
18961                 final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
18962                 final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
18963                         input.reset(), codeFile, /* flags */ 0);
18964                 if (result.isSuccess()) {
18965                     // Ignore error; we tried our best
18966                     allCodePaths = result.getResult().getAllApkPaths();
18967                 }
18968             }
18969 
18970             cleanUp();
18971             removeDexFiles(allCodePaths, instructionSets);
18972         }
18973 
doPostDeleteLI(boolean delete)18974         boolean doPostDeleteLI(boolean delete) {
18975             // XXX err, shouldn't we respect the delete flag?
18976             cleanUpResourcesLI();
18977             return true;
18978         }
18979     }
18980 
18981     /**
18982      * Logic to handle movement of existing installed applications.
18983      */
18984     class MoveInstallArgs extends InstallArgs {
18985         private File codeFile;
18986 
18987         /** New install */
MoveInstallArgs(InstallParams params)18988         MoveInstallArgs(InstallParams params) {
18989             super(params);
18990         }
18991 
copyApk()18992         int copyApk() {
18993             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
18994                     + move.fromUuid + " to " + move.toUuid);
18995             synchronized (mInstaller) {
18996                 try {
18997                     mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
18998                             move.appId, move.seinfo, move.targetSdkVersion,
18999                             move.fromCodePath);
19000                 } catch (InstallerException e) {
19001                     Slog.w(TAG, "Failed to move app", e);
19002                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
19003                 }
19004             }
19005 
19006             final String toPathName = new File(move.fromCodePath).getName();
19007             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), toPathName);
19008             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
19009 
19010             return PackageManager.INSTALL_SUCCEEDED;
19011         }
19012 
doPreInstall(int status)19013         int doPreInstall(int status) {
19014             if (status != PackageManager.INSTALL_SUCCEEDED) {
19015                 cleanUp(move.toUuid);
19016             }
19017             return status;
19018         }
19019 
19020         @Override
doRename(int status, ParsedPackage parsedPackage)19021         boolean doRename(int status, ParsedPackage parsedPackage) {
19022             if (status != PackageManager.INSTALL_SUCCEEDED) {
19023                 cleanUp(move.toUuid);
19024                 return false;
19025             }
19026 
19027             return true;
19028         }
19029 
doPostInstall(int status, int uid)19030         int doPostInstall(int status, int uid) {
19031             if (status == PackageManager.INSTALL_SUCCEEDED) {
19032                 cleanUp(move.fromUuid);
19033             } else {
19034                 cleanUp(move.toUuid);
19035             }
19036             return status;
19037         }
19038 
19039         @Override
getCodePath()19040         String getCodePath() {
19041             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
19042         }
19043 
cleanUp(String volumeUuid)19044         private boolean cleanUp(String volumeUuid) {
19045             final String toPathName = new File(move.fromCodePath).getName();
19046             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
19047                     toPathName);
19048             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
19049             final int[] userIds = mUserManager.getUserIds();
19050             synchronized (mInstallLock) {
19051                 // Clean up both app data and code
19052                 // All package moves are frozen until finished
19053 
19054                 // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
19055                 // this task was only focused on moving data on internal storage.
19056                 // We don't want ART profiles cleared, because they don't move,
19057                 // so we would be deleting the only copy (b/149200535).
19058                 final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
19059                         | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
19060                 for (int userId : userIds) {
19061                     try {
19062                         mInstaller.destroyAppData(volumeUuid, move.packageName, userId, flags, 0);
19063                     } catch (InstallerException e) {
19064                         Slog.w(TAG, String.valueOf(e));
19065                     }
19066                 }
19067                 removeCodePathLI(codeFile);
19068             }
19069             return true;
19070         }
19071 
cleanUpResourcesLI()19072         void cleanUpResourcesLI() {
19073             throw new UnsupportedOperationException();
19074         }
19075 
doPostDeleteLI(boolean delete)19076         boolean doPostDeleteLI(boolean delete) {
19077             throw new UnsupportedOperationException();
19078         }
19079     }
19080 
19081     /**
19082      * Given {@code targetDir}, returns {@code targetDir/~~[randomStrA]/[packageName]-[randomStrB].}
19083      * Makes sure that {@code targetDir/~~[randomStrA]} directory doesn't exist.
19084      * Notice that this method doesn't actually create any directory.
19085      *
19086      * @param targetDir Directory that is two-levels up from the result directory.
19087      * @param packageName Name of the package whose code files are to be installed under the result
19088      *                    directory.
19089      * @return File object for the directory that should hold the code files of {@code packageName}.
19090      */
getNextCodePath(File targetDir, String packageName)19091     private File getNextCodePath(File targetDir, String packageName) {
19092         SecureRandom random = new SecureRandom();
19093         byte[] bytes = new byte[16];
19094         File firstLevelDir;
19095         do {
19096             random.nextBytes(bytes);
19097             String dirName = RANDOM_DIR_PREFIX
19098                     + Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
19099             firstLevelDir = new File(targetDir, dirName);
19100         } while (firstLevelDir.exists());
19101         random.nextBytes(bytes);
19102         String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
19103         return new File(firstLevelDir, packageName + "-" + suffix);
19104     }
19105 
19106     static class PackageInstalledInfo {
19107         String name;
19108         int uid;
19109         // The set of users that originally had this package installed.
19110         int[] origUsers;
19111         // The set of users that now have this package installed.
19112         int[] newUsers;
19113         AndroidPackage pkg;
19114         int returnCode;
19115         String returnMsg;
19116         String installerPackageName;
19117         PackageRemovedInfo removedInfo;
19118         // The set of packages consuming this shared library or null if no consumers exist.
19119         ArrayList<AndroidPackage> libraryConsumers;
19120         PackageFreezer freezer;
19121 
setError(int code, String msg)19122         public void setError(int code, String msg) {
19123             setReturnCode(code);
19124             setReturnMessage(msg);
19125             Slog.w(TAG, msg);
19126         }
19127 
setError(String msg, PackageParserException e)19128         public void setError(String msg, PackageParserException e) {
19129             setReturnCode(e.error);
19130             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
19131             Slog.w(TAG, msg, e);
19132         }
19133 
setError(String msg, PackageManagerException e)19134         public void setError(String msg, PackageManagerException e) {
19135             returnCode = e.error;
19136             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
19137             Slog.w(TAG, msg, e);
19138         }
19139 
setReturnCode(int returnCode)19140         public void setReturnCode(int returnCode) {
19141             this.returnCode = returnCode;
19142         }
19143 
setReturnMessage(String returnMsg)19144         private void setReturnMessage(String returnMsg) {
19145             this.returnMsg = returnMsg;
19146         }
19147 
19148         // In some error cases we want to convey more info back to the observer
19149         String origPackage;
19150         String origPermission;
19151     }
19152 
updateDigest(MessageDigest digest, File file)19153     private static void updateDigest(MessageDigest digest, File file) throws IOException {
19154         try (DigestInputStream digestStream =
19155                 new DigestInputStream(new FileInputStream(file), digest)) {
19156             while (digestStream.read() != -1) {} // nothing to do; just plow through the file
19157         }
19158     }
19159 
removeNativeBinariesLI(PackageSetting ps)19160     private void removeNativeBinariesLI(PackageSetting ps) {
19161         if (ps != null) {
19162             NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
19163         }
19164     }
19165 
19166     @GuardedBy("mLock")
enableSystemPackageLPw(AndroidPackage pkg)19167     private void enableSystemPackageLPw(AndroidPackage pkg) {
19168         mSettings.enableSystemPackageLPw(pkg.getPackageName());
19169     }
19170 
19171     @GuardedBy("mLock")
disableSystemPackageLPw(AndroidPackage oldPkg)19172     private boolean disableSystemPackageLPw(AndroidPackage oldPkg) {
19173         return mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true);
19174     }
19175 
updateSettingsLI(AndroidPackage newPackage, InstallArgs installArgs, int[] allUsers, PackageInstalledInfo res)19176     private void updateSettingsLI(AndroidPackage newPackage, InstallArgs installArgs,
19177             int[] allUsers, PackageInstalledInfo res) {
19178         updateSettingsInternalLI(newPackage, installArgs, allUsers, res);
19179     }
19180 
updateSettingsInternalLI(AndroidPackage pkg, InstallArgs installArgs, int[] allUsers, PackageInstalledInfo res)19181     private void updateSettingsInternalLI(AndroidPackage pkg, InstallArgs installArgs,
19182             int[] allUsers, PackageInstalledInfo res) {
19183         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
19184 
19185         final String pkgName = pkg.getPackageName();
19186         final int[] installedForUsers = res.origUsers;
19187         final int installReason = installArgs.installReason;
19188         InstallSource installSource = installArgs.installSource;
19189         final String installerPackageName = installSource.installerPackageName;
19190 
19191         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getPath());
19192         synchronized (mLock) {
19193             // For system-bundled packages, we assume that installing an upgraded version
19194             // of the package implies that the user actually wants to run that new code,
19195             // so we enable the package.
19196             final PackageSetting ps = mSettings.getPackageLPr(pkgName);
19197             final int userId = installArgs.user.getIdentifier();
19198             if (ps != null) {
19199                 if (pkg.isSystem()) {
19200                     if (DEBUG_INSTALL) {
19201                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
19202                     }
19203                     // Enable system package for requested users
19204                     if (res.origUsers != null) {
19205                         for (int origUserId : res.origUsers) {
19206                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
19207                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
19208                                         origUserId, installerPackageName);
19209                             }
19210                         }
19211                     }
19212                     // Also convey the prior install/uninstall state
19213                     if (allUsers != null && installedForUsers != null) {
19214                         for (int currentUserId : allUsers) {
19215                             final boolean installed = ArrayUtils.contains(
19216                                     installedForUsers, currentUserId);
19217                             if (DEBUG_INSTALL) {
19218                                 Slog.d(TAG, "    user " + currentUserId + " => " + installed);
19219                             }
19220                             ps.setInstalled(installed, currentUserId);
19221                         }
19222                         // these install state changes will be persisted in the
19223                         // upcoming call to mSettings.writeLPr().
19224                     }
19225 
19226                     if (allUsers != null) {
19227                         for (int currentUserId : allUsers) {
19228                             ps.resetOverrideComponentLabelIcon(currentUserId);
19229                         }
19230                     }
19231                 }
19232 
19233                 // Retrieve the overlays for shared libraries of the package.
19234                 if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) {
19235                     for (SharedLibraryInfo sharedLib : ps.getPkgState().getUsesLibraryInfos()) {
19236                         for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
19237                             if (!sharedLib.isDynamic()) {
19238                                 // TODO(146804378): Support overlaying static shared libraries
19239                                 continue;
19240                             }
19241                             final PackageSetting libPs = mSettings.getPackageLPr(
19242                                     sharedLib.getPackageName());
19243                             if (libPs == null) {
19244                                 continue;
19245                             }
19246                             ps.setOverlayPathsForLibrary(sharedLib.getName(),
19247                                     libPs.getOverlayPaths(currentUserId), currentUserId);
19248                         }
19249                     }
19250                 }
19251 
19252                 // It's implied that when a user requests installation, they want the app to be
19253                 // installed and enabled. (This does not apply to USER_ALL, which here means only
19254                 // install on users for which the app is already installed).
19255                 if (userId != UserHandle.USER_ALL) {
19256                     ps.setInstalled(true, userId);
19257                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
19258                 }
19259 
19260                 mSettings.addInstallerPackageNames(ps.installSource);
19261 
19262                 // When replacing an existing package, preserve the original install reason for all
19263                 // users that had the package installed before. Similarly for uninstall reasons.
19264                 final Set<Integer> previousUserIds = new ArraySet<>();
19265                 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
19266                     final int installReasonCount = res.removedInfo.installReasons.size();
19267                     for (int i = 0; i < installReasonCount; i++) {
19268                         final int previousUserId = res.removedInfo.installReasons.keyAt(i);
19269                         final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
19270                         ps.setInstallReason(previousInstallReason, previousUserId);
19271                         previousUserIds.add(previousUserId);
19272                     }
19273                 }
19274                 if (res.removedInfo != null && res.removedInfo.uninstallReasons != null) {
19275                     for (int i = 0; i < res.removedInfo.uninstallReasons.size(); i++) {
19276                         final int previousUserId = res.removedInfo.uninstallReasons.keyAt(i);
19277                         final int previousReason = res.removedInfo.uninstallReasons.valueAt(i);
19278                         ps.setUninstallReason(previousReason, previousUserId);
19279                     }
19280                 }
19281 
19282                 // Set install reason for users that are having the package newly installed.
19283                 final int[] allUsersList = mUserManager.getUserIds();
19284                 if (userId == UserHandle.USER_ALL) {
19285                     // TODO(b/152629990): It appears that the package doesn't actually get newly
19286                     //  installed in this case, so the installReason shouldn't get modified?
19287                     for (int currentUserId : allUsersList) {
19288                         if (!previousUserIds.contains(currentUserId)) {
19289                             ps.setInstallReason(installReason, currentUserId);
19290                         }
19291                     }
19292                 } else if (!previousUserIds.contains(userId)) {
19293                     ps.setInstallReason(installReason, userId);
19294                 }
19295 
19296                 // TODO(b/169721400): generalize Incremental States and create a Callback object
19297                 // that can be used for all the packages.
19298                 final String codePath = ps.getPathString();
19299                 if (IncrementalManager.isIncrementalPath(codePath) && mIncrementalManager != null) {
19300                     final IncrementalStatesCallback incrementalStatesCallback =
19301                             new IncrementalStatesCallback(ps.name,
19302                                     UserHandle.getUid(userId, ps.appId),
19303                                     getInstalledUsers(ps, userId));
19304                     ps.setIncrementalStatesCallback(incrementalStatesCallback);
19305                     mIncrementalManager.registerLoadingProgressCallback(codePath,
19306                             new IncrementalProgressListener(ps.name));
19307                 }
19308 
19309                 // Ensure that the uninstall reason is UNKNOWN for users with the package installed.
19310                 for (int currentUserId : allUsersList) {
19311                     if (ps.getInstalled(currentUserId)) {
19312                         ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, currentUserId);
19313                     }
19314                 }
19315 
19316                 mSettings.writeKernelMappingLPr(ps);
19317 
19318                 final PermissionManagerServiceInternal.PackageInstalledParams.Builder
19319                         permissionParamsBuilder =
19320                         new PermissionManagerServiceInternal.PackageInstalledParams.Builder();
19321                 final boolean grantPermissions = (installArgs.installFlags
19322                         & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
19323                 if (grantPermissions) {
19324                     final List<String> grantedPermissions =
19325                             installArgs.installGrantPermissions != null
19326                                     ? Arrays.asList(installArgs.installGrantPermissions)
19327                                     : pkg.getRequestedPermissions();
19328                     permissionParamsBuilder.setGrantedPermissions(grantedPermissions);
19329                 }
19330                 final boolean allowlistAllRestrictedPermissions =
19331                         (installArgs.installFlags
19332                                 & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0;
19333                 final List<String> allowlistedRestrictedPermissions =
19334                         allowlistAllRestrictedPermissions ? pkg.getRequestedPermissions()
19335                         : installArgs.whitelistedRestrictedPermissions;
19336                 if (allowlistedRestrictedPermissions != null) {
19337                     permissionParamsBuilder.setAllowlistedRestrictedPermissions(
19338                             allowlistedRestrictedPermissions);
19339                 }
19340                 final int autoRevokePermissionsMode = installArgs.autoRevokePermissionsMode;
19341                 permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode);
19342                 mPermissionManager.onPackageInstalled(pkg, permissionParamsBuilder.build(), userId);
19343             }
19344             res.name = pkgName;
19345             res.uid = pkg.getUid();
19346             res.pkg = pkg;
19347             res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
19348             //to update install status
19349             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
19350             writeSettingsLPrTEMP();
19351             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19352         }
19353 
19354         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19355     }
19356 
19357     private static class InstallRequest {
19358         public final InstallArgs args;
19359         public final PackageInstalledInfo installResult;
19360 
InstallRequest(InstallArgs args, PackageInstalledInfo res)19361         private InstallRequest(InstallArgs args, PackageInstalledInfo res) {
19362             this.args = args;
19363             this.installResult = res;
19364         }
19365     }
19366 
19367     @GuardedBy("mInstallLock")
installPackagesTracedLI(List<InstallRequest> requests)19368     private void installPackagesTracedLI(List<InstallRequest> requests) {
19369         try {
19370             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
19371             installPackagesLI(requests);
19372         } finally {
19373             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19374         }
19375     }
19376 
19377     /**
19378      * Package state to commit to memory and disk after reconciliation has completed.
19379      */
19380     private static class CommitRequest {
19381         final Map<String, ReconciledPackage> reconciledPackages;
19382         @NonNull
19383         final int[] mAllUsers;
19384 
CommitRequest(Map<String, ReconciledPackage> reconciledPackages, @NonNull int[] allUsers)19385         private CommitRequest(Map<String, ReconciledPackage> reconciledPackages,
19386                 @NonNull int[] allUsers) {
19387             this.reconciledPackages = reconciledPackages;
19388             this.mAllUsers = allUsers;
19389         }
19390     }
19391 
19392     /**
19393      * Package scan results and related request details used to reconcile the potential addition of
19394      * one or more packages to the system.
19395      *
19396      * Reconcile will take a set of package details that need to be committed to the system and make
19397      * sure that they are valid in the context of the system and the other installing apps. Any
19398      * invalid state or app will result in a failed reconciliation and thus whatever operation (such
19399      * as install) led to the request.
19400      */
19401     private static class ReconcileRequest {
19402         public final Map<String, ScanResult> scannedPackages;
19403 
19404         public final Map<String, AndroidPackage> allPackages;
19405         public final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource;
19406         public final Map<String, InstallArgs> installArgs;
19407         public final Map<String, PackageInstalledInfo> installResults;
19408         public final Map<String, PrepareResult> preparedPackages;
19409         public final Map<String, VersionInfo> versionInfos;
19410         public final Map<String, PackageSetting> lastStaticSharedLibSettings;
19411 
ReconcileRequest(Map<String, ScanResult> scannedPackages, Map<String, InstallArgs> installArgs, Map<String, PackageInstalledInfo> installResults, Map<String, PrepareResult> preparedPackages, Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource, Map<String, AndroidPackage> allPackages, Map<String, VersionInfo> versionInfos, Map<String, PackageSetting> lastStaticSharedLibSettings)19412         private ReconcileRequest(Map<String, ScanResult> scannedPackages,
19413                 Map<String, InstallArgs> installArgs,
19414                 Map<String, PackageInstalledInfo> installResults,
19415                 Map<String, PrepareResult> preparedPackages,
19416                 Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
19417                 Map<String, AndroidPackage> allPackages,
19418                 Map<String, VersionInfo> versionInfos,
19419                 Map<String, PackageSetting> lastStaticSharedLibSettings) {
19420             this.scannedPackages = scannedPackages;
19421             this.installArgs = installArgs;
19422             this.installResults = installResults;
19423             this.preparedPackages = preparedPackages;
19424             this.sharedLibrarySource = sharedLibrarySource;
19425             this.allPackages = allPackages;
19426             this.versionInfos = versionInfos;
19427             this.lastStaticSharedLibSettings = lastStaticSharedLibSettings;
19428         }
19429 
ReconcileRequest(Map<String, ScanResult> scannedPackages, Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource, Map<String, AndroidPackage> allPackages, Map<String, VersionInfo> versionInfos, Map<String, PackageSetting> lastStaticSharedLibSettings)19430         private ReconcileRequest(Map<String, ScanResult> scannedPackages,
19431                 Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
19432                 Map<String, AndroidPackage> allPackages,
19433                 Map<String, VersionInfo> versionInfos,
19434                 Map<String, PackageSetting> lastStaticSharedLibSettings) {
19435             this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
19436                     Collections.emptyMap(), sharedLibrarySource, allPackages, versionInfos,
19437                     lastStaticSharedLibSettings);
19438         }
19439     }
19440     private static class ReconcileFailure extends PackageManagerException {
ReconcileFailure(String message)19441         ReconcileFailure(String message) {
19442             super("Reconcile failed: " + message);
19443         }
ReconcileFailure(int reason, String message)19444         ReconcileFailure(int reason, String message) {
19445             super(reason, "Reconcile failed: " + message);
19446         }
ReconcileFailure(PackageManagerException e)19447         ReconcileFailure(PackageManagerException e) {
19448             this(e.error, e.getMessage());
19449         }
19450     }
19451 
19452     /**
19453      * A container of all data needed to commit a package to in-memory data structures and to disk.
19454      * TODO: move most of the data contained here into a PackageSetting for commit.
19455      */
19456     private static class ReconciledPackage {
19457         public final ReconcileRequest request;
19458         public final PackageSetting pkgSetting;
19459         public final ScanResult scanResult;
19460         // TODO: Remove install-specific details from the reconcile result
19461         public final PackageInstalledInfo installResult;
19462         @Nullable public final PrepareResult prepareResult;
19463         @Nullable public final InstallArgs installArgs;
19464         public final DeletePackageAction deletePackageAction;
19465         public final List<SharedLibraryInfo> allowedSharedLibraryInfos;
19466         public final SigningDetails signingDetails;
19467         public final boolean sharedUserSignaturesChanged;
19468         public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos;
19469         public final boolean removeAppKeySetData;
19470 
ReconciledPackage(ReconcileRequest request, InstallArgs installArgs, PackageSetting pkgSetting, PackageInstalledInfo installResult, PrepareResult prepareResult, ScanResult scanResult, DeletePackageAction deletePackageAction, List<SharedLibraryInfo> allowedSharedLibraryInfos, SigningDetails signingDetails, boolean sharedUserSignaturesChanged, boolean removeAppKeySetData)19471         private ReconciledPackage(ReconcileRequest request,
19472                 InstallArgs installArgs,
19473                 PackageSetting pkgSetting,
19474                 PackageInstalledInfo installResult,
19475                 PrepareResult prepareResult,
19476                 ScanResult scanResult,
19477                 DeletePackageAction deletePackageAction,
19478                 List<SharedLibraryInfo> allowedSharedLibraryInfos,
19479                 SigningDetails signingDetails,
19480                 boolean sharedUserSignaturesChanged,
19481                 boolean removeAppKeySetData) {
19482             this.request = request;
19483             this.installArgs = installArgs;
19484             this.pkgSetting = pkgSetting;
19485             this.installResult = installResult;
19486             this.prepareResult = prepareResult;
19487             this.scanResult = scanResult;
19488             this.deletePackageAction = deletePackageAction;
19489             this.allowedSharedLibraryInfos = allowedSharedLibraryInfos;
19490             this.signingDetails = signingDetails;
19491             this.sharedUserSignaturesChanged = sharedUserSignaturesChanged;
19492             this.removeAppKeySetData = removeAppKeySetData;
19493         }
19494 
19495         /**
19496          * Returns a combined set of packages containing the packages already installed combined
19497          * with the package(s) currently being installed. The to-be installed packages take
19498          * precedence and may shadow already installed packages.
19499          */
getCombinedAvailablePackages()19500         private Map<String, AndroidPackage> getCombinedAvailablePackages() {
19501             final ArrayMap<String, AndroidPackage> combined =
19502                     new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size());
19503 
19504             combined.putAll(request.allPackages);
19505 
19506             for (ScanResult scanResult : request.scannedPackages.values()) {
19507                 combined.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
19508             }
19509 
19510             return combined;
19511         }
19512     }
19513 
19514     @GuardedBy("mLock")
reconcilePackagesLocked( final ReconcileRequest request, KeySetManagerService ksms, Injector injector)19515     private static Map<String, ReconciledPackage> reconcilePackagesLocked(
19516             final ReconcileRequest request, KeySetManagerService ksms, Injector injector)
19517             throws ReconcileFailure {
19518         final Map<String, ScanResult> scannedPackages = request.scannedPackages;
19519 
19520         final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size());
19521 
19522         // make a copy of the existing set of packages so we can combine them with incoming packages
19523         final ArrayMap<String, AndroidPackage> combinedPackages =
19524                 new ArrayMap<>(request.allPackages.size() + scannedPackages.size());
19525 
19526         combinedPackages.putAll(request.allPackages);
19527 
19528         final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> incomingSharedLibraries =
19529                 new ArrayMap<>();
19530 
19531         for (String installPackageName : scannedPackages.keySet()) {
19532             final ScanResult scanResult = scannedPackages.get(installPackageName);
19533 
19534             // add / replace existing with incoming packages
19535             combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
19536 
19537             // in the first pass, we'll build up the set of incoming shared libraries
19538             final List<SharedLibraryInfo> allowedSharedLibInfos =
19539                     getAllowedSharedLibInfos(scanResult, request.sharedLibrarySource);
19540             final SharedLibraryInfo staticLib = scanResult.staticSharedLibraryInfo;
19541             if (allowedSharedLibInfos != null) {
19542                 for (SharedLibraryInfo info : allowedSharedLibInfos) {
19543                     if (!addSharedLibraryToPackageVersionMap(incomingSharedLibraries, info)) {
19544                         throw new ReconcileFailure("Static Shared Library " + staticLib.getName()
19545                                 + " is being installed twice in this set!");
19546                     }
19547                 }
19548             }
19549 
19550             // the following may be null if we're just reconciling on boot (and not during install)
19551             final InstallArgs installArgs = request.installArgs.get(installPackageName);
19552             final PackageInstalledInfo res = request.installResults.get(installPackageName);
19553             final PrepareResult prepareResult = request.preparedPackages.get(installPackageName);
19554             final boolean isInstall = installArgs != null;
19555             if (isInstall && (res == null || prepareResult == null)) {
19556                 throw new ReconcileFailure("Reconcile arguments are not balanced for "
19557                         + installPackageName + "!");
19558             }
19559 
19560             final DeletePackageAction deletePackageAction;
19561             // we only want to try to delete for non system apps
19562             if (isInstall && prepareResult.replace && !prepareResult.system) {
19563                 final boolean killApp = (scanResult.request.scanFlags & SCAN_DONT_KILL_APP) == 0;
19564                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
19565                         | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
19566                 deletePackageAction = mayDeletePackageLocked(res.removedInfo,
19567                         prepareResult.originalPs, prepareResult.disabledPs,
19568                         deleteFlags, null /* all users */);
19569                 if (deletePackageAction == null) {
19570                     throw new ReconcileFailure(
19571                             PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
19572                             "May not delete " + installPackageName + " to replace");
19573                 }
19574             } else {
19575                 deletePackageAction = null;
19576             }
19577 
19578             final int scanFlags = scanResult.request.scanFlags;
19579             final int parseFlags = scanResult.request.parseFlags;
19580             final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
19581 
19582             final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting;
19583             final PackageSetting lastStaticSharedLibSetting =
19584                     request.lastStaticSharedLibSettings.get(installPackageName);
19585             final PackageSetting signatureCheckPs =
19586                     (prepareResult != null && lastStaticSharedLibSetting != null)
19587                             ? lastStaticSharedLibSetting
19588                             : scanResult.pkgSetting;
19589             boolean removeAppKeySetData = false;
19590             boolean sharedUserSignaturesChanged = false;
19591             SigningDetails signingDetails = null;
19592             if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
19593                 if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
19594                     // We just determined the app is signed correctly, so bring
19595                     // over the latest parsed certs.
19596                 } else {
19597                     if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) {
19598                         throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
19599                                 "Package " + parsedPackage.getPackageName()
19600                                         + " upgrade keys do not match the previously installed"
19601                                         + " version");
19602                     } else {
19603                         String msg = "System package " + parsedPackage.getPackageName()
19604                                 + " signature changed; retaining data.";
19605                         reportSettingsProblem(Log.WARN, msg);
19606                     }
19607                 }
19608                 signingDetails = parsedPackage.getSigningDetails();
19609             } else {
19610                 try {
19611                     final VersionInfo versionInfo = request.versionInfos.get(installPackageName);
19612                     final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
19613                     final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
19614                     final boolean isRollback = installArgs != null
19615                             && installArgs.installReason == PackageManager.INSTALL_REASON_ROLLBACK;
19616                     final boolean compatMatch = verifySignatures(signatureCheckPs,
19617                             disabledPkgSetting, parsedPackage.getSigningDetails(), compareCompat,
19618                             compareRecover, isRollback);
19619                     // The new KeySets will be re-added later in the scanning process.
19620                     if (compatMatch) {
19621                         removeAppKeySetData = true;
19622                     }
19623                     // We just determined the app is signed correctly, so bring
19624                     // over the latest parsed certs.
19625                     signingDetails = parsedPackage.getSigningDetails();
19626 
19627 
19628                     // if this is is a sharedUser, check to see if the new package is signed by a
19629                     // newer
19630                     // signing certificate than the existing one, and if so, copy over the new
19631                     // details
19632                     if (signatureCheckPs.sharedUser != null) {
19633                         // Attempt to merge the existing lineage for the shared SigningDetails with
19634                         // the lineage of the new package; if the shared SigningDetails are not
19635                         // returned this indicates the new package added new signers to the lineage
19636                         // and/or changed the capabilities of existing signers in the lineage.
19637                         SigningDetails sharedSigningDetails =
19638                                 signatureCheckPs.sharedUser.signatures.mSigningDetails;
19639                         SigningDetails mergedDetails = sharedSigningDetails.mergeLineageWith(
19640                                 signingDetails);
19641                         if (mergedDetails != sharedSigningDetails) {
19642                             signatureCheckPs.sharedUser.signatures.mSigningDetails = mergedDetails;
19643                         }
19644                         if (signatureCheckPs.sharedUser.signaturesChanged == null) {
19645                             signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
19646                         }
19647                     }
19648                 } catch (PackageManagerException e) {
19649                     if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) {
19650                         throw new ReconcileFailure(e);
19651                     }
19652                     signingDetails = parsedPackage.getSigningDetails();
19653 
19654                     // If the system app is part of a shared user we allow that shared user to
19655                     // change
19656                     // signatures as well as part of an OTA. We still need to verify that the
19657                     // signatures
19658                     // are consistent within the shared user for a given boot, so only allow
19659                     // updating
19660                     // the signatures on the first package scanned for the shared user (i.e. if the
19661                     // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
19662                     if (signatureCheckPs.sharedUser != null) {
19663                         final Signature[] sharedUserSignatures =
19664                                 signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures;
19665                         if (signatureCheckPs.sharedUser.signaturesChanged != null
19666                                 && compareSignatures(sharedUserSignatures,
19667                                 parsedPackage.getSigningDetails().signatures)
19668                                         != PackageManager.SIGNATURE_MATCH) {
19669                             if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
19670                                 // Mismatched signatures is an error and silently skipping system
19671                                 // packages will likely break the device in unforeseen ways.
19672                                 // However, we allow the device to boot anyway because, prior to Q,
19673                                 // vendors were not expecting the platform to crash in this
19674                                 // situation.
19675                                 // This WILL be a hard failure on any new API levels after Q.
19676                                 throw new ReconcileFailure(
19677                                         INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
19678                                         "Signature mismatch for shared user: "
19679                                                 + scanResult.pkgSetting.sharedUser);
19680                             } else {
19681                                 // Treat mismatched signatures on system packages using a shared
19682                                 // UID as
19683                                 // fatal for the system overall, rather than just failing to install
19684                                 // whichever package happened to be scanned later.
19685                                 throw new IllegalStateException(
19686                                         "Signature mismatch on system package "
19687                                                 + parsedPackage.getPackageName()
19688                                                 + " for shared user "
19689                                                 + scanResult.pkgSetting.sharedUser);
19690                             }
19691                         }
19692 
19693                         sharedUserSignaturesChanged = true;
19694                         signatureCheckPs.sharedUser.signatures.mSigningDetails =
19695                                 parsedPackage.getSigningDetails();
19696                         signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
19697                     }
19698                     // File a report about this.
19699                     String msg = "System package " + parsedPackage.getPackageName()
19700                             + " signature changed; retaining data.";
19701                     reportSettingsProblem(Log.WARN, msg);
19702                 } catch (IllegalArgumentException e) {
19703                     // should never happen: certs matched when checking, but not when comparing
19704                     // old to new for sharedUser
19705                     throw new RuntimeException(
19706                             "Signing certificates comparison made on incomparable signing details"
19707                                     + " but somehow passed verifySignatures!", e);
19708                 }
19709             }
19710 
19711             result.put(installPackageName,
19712                     new ReconciledPackage(request, installArgs, scanResult.pkgSetting,
19713                             res, request.preparedPackages.get(installPackageName), scanResult,
19714                             deletePackageAction, allowedSharedLibInfos, signingDetails,
19715                             sharedUserSignaturesChanged, removeAppKeySetData));
19716         }
19717 
19718         for (String installPackageName : scannedPackages.keySet()) {
19719             // Check all shared libraries and map to their actual file path.
19720             // We only do this here for apps not on a system dir, because those
19721             // are the only ones that can fail an install due to this.  We
19722             // will take care of the system apps by updating all of their
19723             // library paths after the scan is done. Also during the initial
19724             // scan don't update any libs as we do this wholesale after all
19725             // apps are scanned to avoid dependency based scanning.
19726             final ScanResult scanResult = scannedPackages.get(installPackageName);
19727             if ((scanResult.request.scanFlags & SCAN_BOOTING) != 0
19728                     || (scanResult.request.parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR)
19729                     != 0) {
19730                 continue;
19731             }
19732             try {
19733                 result.get(installPackageName).collectedSharedLibraryInfos =
19734                         collectSharedLibraryInfos(scanResult.request.parsedPackage,
19735                                 combinedPackages, request.sharedLibrarySource,
19736                                 incomingSharedLibraries, injector.getCompatibility());
19737 
19738             } catch (PackageManagerException e) {
19739                 throw new ReconcileFailure(e.error, e.getMessage());
19740             }
19741         }
19742 
19743         return result;
19744     }
19745 
19746     /**
19747      * Compare the newly scanned package with current system state to see which of its declared
19748      * shared libraries should be allowed to be added to the system.
19749      */
getAllowedSharedLibInfos( ScanResult scanResult, Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingSharedLibraries)19750     private static List<SharedLibraryInfo> getAllowedSharedLibInfos(
19751             ScanResult scanResult,
19752             Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingSharedLibraries) {
19753         // Let's used the parsed package as scanResult.pkgSetting may be null
19754         final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
19755         if (scanResult.staticSharedLibraryInfo == null
19756                 && scanResult.dynamicSharedLibraryInfos == null) {
19757             return null;
19758         }
19759 
19760         // Any app can add new static shared libraries
19761         if (scanResult.staticSharedLibraryInfo != null) {
19762             return Collections.singletonList(scanResult.staticSharedLibraryInfo);
19763         }
19764         final boolean hasDynamicLibraries = parsedPackage.isSystem()
19765                         && scanResult.dynamicSharedLibraryInfos != null;
19766         if (!hasDynamicLibraries) {
19767             return null;
19768         }
19769         final boolean isUpdatedSystemApp = scanResult.pkgSetting.getPkgState()
19770                 .isUpdatedSystemApp();
19771         // We may not yet have disabled the updated package yet, so be sure to grab the
19772         // current setting if that's the case.
19773         final PackageSetting updatedSystemPs = isUpdatedSystemApp
19774                 ? scanResult.request.disabledPkgSetting == null
19775                         ? scanResult.request.oldPkgSetting
19776                         : scanResult.request.disabledPkgSetting
19777                 : null;
19778         if (isUpdatedSystemApp && (updatedSystemPs.pkg == null
19779                 || updatedSystemPs.pkg.getLibraryNames() == null)) {
19780             Slog.w(TAG, "Package " + parsedPackage.getPackageName()
19781                     + " declares libraries that are not declared on the system image; skipping");
19782             return null;
19783         }
19784         final ArrayList<SharedLibraryInfo> infos =
19785                 new ArrayList<>(scanResult.dynamicSharedLibraryInfos.size());
19786         for (SharedLibraryInfo info : scanResult.dynamicSharedLibraryInfos) {
19787             final String name = info.getName();
19788             if (isUpdatedSystemApp) {
19789                 // New library entries can only be added through the
19790                 // system image.  This is important to get rid of a lot
19791                 // of nasty edge cases: for example if we allowed a non-
19792                 // system update of the app to add a library, then uninstalling
19793                 // the update would make the library go away, and assumptions
19794                 // we made such as through app install filtering would now
19795                 // have allowed apps on the device which aren't compatible
19796                 // with it.  Better to just have the restriction here, be
19797                 // conservative, and create many fewer cases that can negatively
19798                 // impact the user experience.
19799                 if (!updatedSystemPs.pkg.getLibraryNames().contains(name)) {
19800                     Slog.w(TAG, "Package " + parsedPackage.getPackageName()
19801                             + " declares library " + name
19802                             + " that is not declared on system image; skipping");
19803                     continue;
19804                 }
19805             }
19806             if (sharedLibExists(
19807                     name, SharedLibraryInfo.VERSION_UNDEFINED, existingSharedLibraries)) {
19808                 Slog.w(TAG, "Package " + parsedPackage.getPackageName() + " declares library "
19809                         + name + " that already exists; skipping");
19810                 continue;
19811             }
19812             infos.add(info);
19813         }
19814         return infos;
19815     }
19816 
19817     /**
19818      * Returns false if the adding shared library already exists in the map and so could not be
19819      * added.
19820      */
addSharedLibraryToPackageVersionMap( Map<String, WatchedLongSparseArray<SharedLibraryInfo>> target, SharedLibraryInfo library)19821     private static boolean addSharedLibraryToPackageVersionMap(
19822             Map<String, WatchedLongSparseArray<SharedLibraryInfo>> target,
19823             SharedLibraryInfo library) {
19824         final String name = library.getName();
19825         if (target.containsKey(name)) {
19826             if (library.getType() != SharedLibraryInfo.TYPE_STATIC) {
19827                 // We've already added this non-version-specific library to the map.
19828                 return false;
19829             } else if (target.get(name).indexOfKey(library.getLongVersion()) >= 0) {
19830                 // We've already added this version of a version-specific library to the map.
19831                 return false;
19832             }
19833         } else {
19834             target.put(name, new WatchedLongSparseArray<>());
19835         }
19836         target.get(name).put(library.getLongVersion(), library);
19837         return true;
19838     }
19839 
19840     @GuardedBy("mLock")
commitPackagesLocked(final CommitRequest request)19841     private void commitPackagesLocked(final CommitRequest request) {
19842         // TODO: remove any expected failures from this method; this should only be able to fail due
19843         //       to unavoidable errors (I/O, etc.)
19844         for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) {
19845             final ScanResult scanResult = reconciledPkg.scanResult;
19846             final ScanRequest scanRequest = scanResult.request;
19847             final ParsedPackage parsedPackage = scanRequest.parsedPackage;
19848             final String packageName = parsedPackage.getPackageName();
19849             final PackageInstalledInfo res = reconciledPkg.installResult;
19850 
19851             if (reconciledPkg.prepareResult.replace) {
19852                 AndroidPackage oldPackage = mPackages.get(packageName);
19853 
19854                 // Set the update and install times
19855                 PackageSetting deletedPkgSetting = getPackageSetting(oldPackage.getPackageName());
19856                 reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime;
19857                 reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();
19858 
19859                 res.removedInfo.broadcastAllowList = mAppsFilter.getVisibilityAllowList(
19860                         reconciledPkg.pkgSetting, request.mAllUsers, mSettings.getPackagesLocked());
19861                 if (reconciledPkg.prepareResult.system) {
19862                     // Remove existing system package
19863                     removePackageLI(oldPackage, true);
19864                     if (!disableSystemPackageLPw(oldPackage)) {
19865                         // We didn't need to disable the .apk as a current system package,
19866                         // which means we are replacing another update that is already
19867                         // installed.  We need to make sure to delete the older one's .apk.
19868                         res.removedInfo.args = createInstallArgsForExisting(
19869                                 oldPackage.getPath(),
19870                                 getAppDexInstructionSets(
19871                                         AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
19872                                                 deletedPkgSetting),
19873                                         AndroidPackageUtils.getSecondaryCpuAbi(oldPackage,
19874                                                 deletedPkgSetting)));
19875                     } else {
19876                         res.removedInfo.args = null;
19877                     }
19878                 } else {
19879                     try {
19880                         // Settings will be written during the call to updateSettingsLI().
19881                         executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
19882                                 true, request.mAllUsers, false, parsedPackage);
19883                     } catch (SystemDeleteException e) {
19884                         if (mIsEngBuild) {
19885                             throw new RuntimeException("Unexpected failure", e);
19886                             // ignore; not possible for non-system app
19887                         }
19888                     }
19889                     // Successfully deleted the old package; proceed with replace.
19890 
19891                     // If deleted package lived in a container, give users a chance to
19892                     // relinquish resources before killing.
19893                     if (oldPackage.isExternalStorage()) {
19894                         if (DEBUG_INSTALL) {
19895                             Slog.i(TAG, "upgrading pkg " + oldPackage
19896                                     + " is ASEC-hosted -> UNAVAILABLE");
19897                         }
19898                         final int[] uidArray = new int[]{oldPackage.getUid()};
19899                         final ArrayList<String> pkgList = new ArrayList<>(1);
19900                         pkgList.add(oldPackage.getPackageName());
19901                         sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
19902                     }
19903 
19904                     // Update the in-memory copy of the previous code paths.
19905                     PackageSetting ps1 = mSettings.getPackageLPr(
19906                             reconciledPkg.prepareResult.existingPackage.getPackageName());
19907                     if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP)
19908                             == 0) {
19909                         if (ps1.mOldCodePaths == null) {
19910                             ps1.mOldCodePaths = new ArraySet<>();
19911                         }
19912                         Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseApkPath());
19913                         if (oldPackage.getSplitCodePaths() != null) {
19914                             Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths());
19915                         }
19916                     } else {
19917                         ps1.mOldCodePaths = null;
19918                     }
19919 
19920                     if (reconciledPkg.installResult.returnCode
19921                             == PackageManager.INSTALL_SUCCEEDED) {
19922                         PackageSetting ps2 = mSettings.getPackageLPr(
19923                                 parsedPackage.getPackageName());
19924                         if (ps2 != null) {
19925                             res.removedInfo.removedForAllUsers = mPackages.get(ps2.name) == null;
19926                         }
19927                     }
19928                 }
19929             }
19930 
19931             AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg, request.mAllUsers);
19932             updateSettingsLI(pkg, reconciledPkg.installArgs, request.mAllUsers, res);
19933 
19934             final PackageSetting ps = mSettings.getPackageLPr(packageName);
19935             if (ps != null) {
19936                 res.newUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
19937                 ps.setUpdateAvailable(false /*updateAvailable*/);
19938             }
19939             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
19940                 updateSequenceNumberLP(ps, res.newUsers);
19941                 updateInstantAppInstallerLocked(packageName);
19942             }
19943         }
19944         ApplicationPackageManager.invalidateGetPackagesForUidCache();
19945     }
19946 
19947     /**
19948      * Installs one or more packages atomically. This operation is broken up into four phases:
19949      * <ul>
19950      *     <li><b>Prepare</b>
19951      *         <br/>Analyzes any current install state, parses the package and does initial
19952      *         validation on it.</li>
19953      *     <li><b>Scan</b>
19954      *         <br/>Interrogates the parsed packages given the context collected in prepare.</li>
19955      *     <li><b>Reconcile</b>
19956      *         <br/>Validates scanned packages in the context of each other and the current system
19957      *         state to ensure that the install will be successful.
19958      *     <li><b>Commit</b>
19959      *         <br/>Commits all scanned packages and updates system state. This is the only place
19960      *         that system state may be modified in the install flow and all predictable errors
19961      *         must be determined before this phase.</li>
19962      * </ul>
19963      *
19964      * Failure at any phase will result in a full failure to install all packages.
19965      */
19966     @GuardedBy("mInstallLock")
installPackagesLI(List<InstallRequest> requests)19967     private void installPackagesLI(List<InstallRequest> requests) {
19968         final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
19969         final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
19970         final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
19971         final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
19972         final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
19973         final Map<String, PackageSetting> lastStaticSharedLibSettings =
19974                 new ArrayMap<>(requests.size());
19975         final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
19976         boolean success = false;
19977         try {
19978             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
19979             for (InstallRequest request : requests) {
19980                 // TODO(b/109941548): remove this once we've pulled everything from it and into
19981                 //                    scan, reconcile or commit.
19982                 final PrepareResult prepareResult;
19983                 try {
19984                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
19985                     prepareResult =
19986                             preparePackageLI(request.args, request.installResult);
19987                 } catch (PrepareFailure prepareFailure) {
19988                     request.installResult.setError(prepareFailure.error,
19989                             prepareFailure.getMessage());
19990                     request.installResult.origPackage = prepareFailure.conflictingPackage;
19991                     request.installResult.origPermission = prepareFailure.conflictingPermission;
19992                     return;
19993                 } finally {
19994                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19995                 }
19996                 request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
19997                 request.installResult.installerPackageName =
19998                         request.args.installSource.installerPackageName;
19999 
20000                 final String packageName = prepareResult.packageToScan.getPackageName();
20001                 prepareResults.put(packageName, prepareResult);
20002                 installResults.put(packageName, request.installResult);
20003                 installArgs.put(packageName, request.args);
20004                 try {
20005                     final ScanResult result = scanPackageTracedLI(
20006                             prepareResult.packageToScan, prepareResult.parseFlags,
20007                             prepareResult.scanFlags, System.currentTimeMillis(),
20008                             request.args.user, request.args.abiOverride);
20009                     if (null != preparedScans.put(result.pkgSetting.pkg.getPackageName(), result)) {
20010                         request.installResult.setError(
20011                                 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
20012                                 "Duplicate package " + result.pkgSetting.pkg.getPackageName()
20013                                         + " in multi-package install request.");
20014                         return;
20015                     }
20016                     createdAppId.put(packageName, optimisticallyRegisterAppId(result));
20017                     versionInfos.put(result.pkgSetting.pkg.getPackageName(),
20018                             getSettingsVersionForPackage(result.pkgSetting.pkg));
20019                     if (result.staticSharedLibraryInfo != null) {
20020                         final PackageSetting sharedLibLatestVersionSetting =
20021                                 getSharedLibLatestVersionSetting(result);
20022                         if (sharedLibLatestVersionSetting != null) {
20023                             lastStaticSharedLibSettings.put(result.pkgSetting.pkg.getPackageName(),
20024                                     sharedLibLatestVersionSetting);
20025                         }
20026                     }
20027                 } catch (PackageManagerException e) {
20028                     request.installResult.setError("Scanning Failed.", e);
20029                     return;
20030                 }
20031             }
20032             ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
20033                     installResults,
20034                     prepareResults,
20035                     mSharedLibraries,
20036                     Collections.unmodifiableMap(mPackages), versionInfos,
20037                     lastStaticSharedLibSettings);
20038             CommitRequest commitRequest = null;
20039             synchronized (mLock) {
20040                 Map<String, ReconciledPackage> reconciledPackages;
20041                 try {
20042                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
20043                     reconciledPackages = reconcilePackagesLocked(
20044                             reconcileRequest, mSettings.getKeySetManagerService(), mInjector);
20045                 } catch (ReconcileFailure e) {
20046                     for (InstallRequest request : requests) {
20047                         request.installResult.setError("Reconciliation failed...", e);
20048                     }
20049                     return;
20050                 } finally {
20051                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20052                 }
20053                 try {
20054                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
20055                     commitRequest = new CommitRequest(reconciledPackages,
20056                             mUserManager.getUserIds());
20057                     commitPackagesLocked(commitRequest);
20058                     success = true;
20059                 } finally {
20060                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20061                 }
20062             }
20063             executePostCommitSteps(commitRequest);
20064         } finally {
20065             if (success) {
20066                 for (InstallRequest request : requests) {
20067                     final InstallArgs args = request.args;
20068                     if (args.mDataLoaderType != DataLoaderType.INCREMENTAL) {
20069                         continue;
20070                     }
20071                     if (args.signingDetails.signatureSchemeVersion != SIGNING_BLOCK_V4) {
20072                         continue;
20073                     }
20074                     // For incremental installs, we bypass the verifier prior to install. Now
20075                     // that we know the package is valid, send a notice to the verifier with
20076                     // the root hash of the base.apk.
20077                     final String baseCodePath = request.installResult.pkg.getBaseApkPath();
20078                     final String[] splitCodePaths = request.installResult.pkg.getSplitCodePaths();
20079                     final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
20080                     final int verificationId = mPendingVerificationToken++;
20081                     final String rootHashString = PackageManagerServiceUtils
20082                             .buildVerificationRootHashString(baseCodePath, splitCodePaths);
20083                     broadcastPackageVerified(verificationId, originUri,
20084                             PackageManager.VERIFICATION_ALLOW, rootHashString,
20085                             args.mDataLoaderType, args.getUser());
20086                 }
20087             } else {
20088                 for (ScanResult result : preparedScans.values()) {
20089                     if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(),
20090                             false)) {
20091                         cleanUpAppIdCreation(result);
20092                     }
20093                 }
20094                 // TODO(patb): create a more descriptive reason than unknown in future release
20095                 // mark all non-failure installs as UNKNOWN so we do not treat them as success
20096                 for (InstallRequest request : requests) {
20097                     if (request.installResult.freezer != null) {
20098                         request.installResult.freezer.close();
20099                     }
20100                     if (request.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) {
20101                         request.installResult.returnCode = PackageManager.INSTALL_UNKNOWN;
20102                     }
20103                 }
20104             }
20105             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20106         }
20107     }
20108 
20109     /**
20110      * On successful install, executes remaining steps after commit completes and the package lock
20111      * is released. These are typically more expensive or require calls to installd, which often
20112      * locks on {@link #mLock}.
20113      */
executePostCommitSteps(CommitRequest commitRequest)20114     private void executePostCommitSteps(CommitRequest commitRequest) {
20115         final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();
20116         for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
20117             final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags
20118                             & PackageManagerService.SCAN_AS_INSTANT_APP) != 0);
20119             final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg;
20120             final String packageName = pkg.getPackageName();
20121             final String codePath = pkg.getPath();
20122             final boolean onIncremental = mIncrementalManager != null
20123                     && isIncrementalPath(codePath);
20124             if (onIncremental) {
20125                 IncrementalStorage storage = mIncrementalManager.openStorage(codePath);
20126                 if (storage == null) {
20127                     throw new IllegalArgumentException(
20128                             "Install: null storage for incremental package " + packageName);
20129                 }
20130                 incrementalStorages.add(storage);
20131             }
20132             prepareAppDataAfterInstallLIF(pkg);
20133             if (reconciledPkg.prepareResult.clearCodeCache) {
20134                 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
20135                         | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20136             }
20137             if (reconciledPkg.prepareResult.replace) {
20138                 mDexManager.notifyPackageUpdated(pkg.getPackageName(),
20139                         pkg.getBaseApkPath(), pkg.getSplitCodePaths());
20140             }
20141 
20142             // Prepare the application profiles for the new code paths.
20143             // This needs to be done before invoking dexopt so that any install-time profile
20144             // can be used for optimizations.
20145             mArtManagerService.prepareAppProfiles(
20146                     pkg,
20147                     resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),
20148                     /* updateReferenceProfileContent= */ true);
20149 
20150             // Compute the compilation reason from the installation scenario.
20151             final int compilationReason = mDexManager.getCompilationReasonForInstallScenario(
20152                     reconciledPkg.installArgs.mInstallScenario);
20153 
20154             // Construct the DexoptOptions early to see if we should skip running dexopt.
20155             //
20156             // Do not run PackageDexOptimizer through the local performDexOpt
20157             // method because `pkg` may not be in `mPackages` yet.
20158             //
20159             // Also, don't fail application installs if the dexopt step fails.
20160             final boolean isBackupOrRestore =
20161                     reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_RESTORE
20162                     || reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_SETUP;
20163 
20164             final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
20165                     | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE
20166                     | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);
20167             DexoptOptions dexoptOptions =
20168                     new DexoptOptions(packageName, compilationReason, dexoptFlags);
20169 
20170             // Check whether we need to dexopt the app.
20171             //
20172             // NOTE: it is IMPORTANT to call dexopt:
20173             //   - after doRename which will sync the package data from AndroidPackage and
20174             //     its corresponding ApplicationInfo.
20175             //   - after installNewPackageLIF or replacePackageLIF which will update result with the
20176             //     uid of the application (pkg.applicationInfo.uid).
20177             //     This update happens in place!
20178             //
20179             // We only need to dexopt if the package meets ALL of the following conditions:
20180             //   1) it is not an instant app or if it is then dexopt is enabled via gservices.
20181             //   2) it is not debuggable.
20182             //   3) it is not on Incremental File System.
20183             //
20184             // Note that we do not dexopt instant apps by default. dexopt can take some time to
20185             // complete, so we skip this step during installation. Instead, we'll take extra time
20186             // the first time the instant app starts. It's preferred to do it this way to provide
20187             // continuous progress to the useur instead of mysteriously blocking somewhere in the
20188             // middle of running an instant app. The default behaviour can be overridden
20189             // via gservices.
20190             //
20191             // Furthermore, dexopt may be skipped, depending on the install scenario and current
20192             // state of the device.
20193             //
20194             // TODO(b/174695087): instantApp and onIncremental should be removed and their install
20195             //       path moved to SCENARIO_FAST.
20196             final boolean performDexopt =
20197                     (!instantApp || Global.getInt(mContext.getContentResolver(),
20198                     Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
20199                     && !pkg.isDebuggable()
20200                     && (!onIncremental)
20201                     && dexoptOptions.isCompilationEnabled();
20202 
20203             if (performDexopt) {
20204                 // Compile the layout resources.
20205                 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
20206                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
20207                     mViewCompiler.compileLayouts(pkg);
20208                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20209                 }
20210 
20211                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
20212                 ScanResult result = reconciledPkg.scanResult;
20213 
20214                 // This mirrors logic from commitReconciledScanResultLocked, where the library files
20215                 // needed for dexopt are assigned.
20216                 // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous
20217                 //  setting needs to be passed to have a comparison, hide it behind an immutable
20218                 //  interface. There's no good reason to have 3 different ways to access the real
20219                 //  PackageSetting object, only one of which is actually correct.
20220                 PackageSetting realPkgSetting = result.existingSettingCopied
20221                         ? result.request.pkgSetting : result.pkgSetting;
20222                 if (realPkgSetting == null) {
20223                     realPkgSetting = reconciledPkg.pkgSetting;
20224                 }
20225 
20226                 // Unfortunately, the updated system app flag is only tracked on this PackageSetting
20227                 boolean isUpdatedSystemApp = reconciledPkg.pkgSetting.getPkgState()
20228                         .isUpdatedSystemApp();
20229 
20230                 realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);
20231 
20232                 mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,
20233                         null /* instructionSets */,
20234                         getOrCreateCompilerPackageStats(pkg),
20235                         mDexManager.getPackageUseInfoOrDefault(packageName),
20236                         dexoptOptions);
20237                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20238             }
20239 
20240             // Notify BackgroundDexOptService that the package has been changed.
20241             // If this is an update of a package which used to fail to compile,
20242             // BackgroundDexOptService will remove it from its denylist.
20243             // TODO: Layering violation
20244             BackgroundDexOptService.notifyPackageChanged(packageName);
20245 
20246             notifyPackageChangeObserversOnUpdate(reconciledPkg);
20247         }
20248         waitForNativeBinariesExtraction(incrementalStorages);
20249     }
20250 
waitForNativeBinariesExtraction( ArraySet<IncrementalStorage> incrementalStorages)20251     static void waitForNativeBinariesExtraction(
20252             ArraySet<IncrementalStorage> incrementalStorages) {
20253         if (incrementalStorages.isEmpty()) {
20254             return;
20255         }
20256         try {
20257             // Native library extraction may take very long time: each page could potentially
20258             // wait for either 10s or 100ms (adb vs non-adb data loader), and that easily adds
20259             // up to a full watchdog timeout of 1 min, killing the system after that. It doesn't
20260             // make much sense as blocking here doesn't lock up the framework, but only blocks
20261             // the installation session and the following ones.
20262             Watchdog.getInstance().pauseWatchingCurrentThread("native_lib_extract");
20263             for (int i = 0; i < incrementalStorages.size(); ++i) {
20264                 IncrementalStorage storage = incrementalStorages.valueAtUnchecked(i);
20265                 storage.waitForNativeBinariesExtraction();
20266             }
20267         } finally {
20268             Watchdog.getInstance().resumeWatchingCurrentThread("native_lib_extract");
20269         }
20270     }
20271 
getInstalledUsers(PackageSetting ps, int userId)20272     private int[] getInstalledUsers(PackageSetting ps, int userId) {
20273         final int[] allUserIds = resolveUserIds(userId);
20274         final ArrayList<Integer> installedUserIdsList = new ArrayList<>();
20275         for (int i = 0; i < allUserIds.length; i++) {
20276             if (ps.getInstalled(allUserIds[i])) {
20277                 installedUserIdsList.add(allUserIds[i]);
20278             }
20279         }
20280         final int numInstalledUserId = installedUserIdsList.size();
20281         final int[] installedUserIds = new int[numInstalledUserId];
20282         for (int i = 0; i < numInstalledUserId; i++) {
20283             installedUserIds[i] = installedUserIdsList.get(i);
20284         }
20285         return installedUserIds;
20286     }
20287 
20288     /**
20289      * Package states callback, used to listen for package state changes and send broadcasts
20290      */
20291     private final class IncrementalStatesCallback implements IncrementalStates.Callback {
20292         private final String mPackageName;
20293         private final int mUid;
20294         private final int[] mInstalledUserIds;
IncrementalStatesCallback(String packageName, int uid, int[] installedUserIds)20295         IncrementalStatesCallback(String packageName, int uid, int[] installedUserIds) {
20296             mPackageName = packageName;
20297             mUid = uid;
20298             mInstalledUserIds = installedUserIds;
20299         }
20300 
20301         @Override
onPackageFullyLoaded()20302         public void onPackageFullyLoaded() {
20303             final SparseArray<int[]> newBroadcastAllowList;
20304             final String codePath;
20305             synchronized (mLock) {
20306                 final PackageSetting ps = mSettings.getPackageLPr(mPackageName);
20307                 if (ps == null) {
20308                     return;
20309                 }
20310                 newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
20311                         ps, mInstalledUserIds, mSettings.getPackagesLocked());
20312                 codePath = ps.getPathString();
20313             }
20314             // Unregister progress listener
20315             mIncrementalManager.unregisterLoadingProgressCallbacks(codePath);
20316             // Make sure the information is preserved
20317             scheduleWriteSettingsLocked();
20318         }
20319     }
20320 
20321     /**
20322      * Loading progress callback, used to listen for progress changes and update package setting
20323      */
20324     private class IncrementalProgressListener extends IPackageLoadingProgressCallback.Stub {
20325         private final String mPackageName;
IncrementalProgressListener(String packageName)20326         IncrementalProgressListener(String packageName) {
20327             mPackageName = packageName;
20328         }
20329 
20330         @Override
onPackageLoadingProgressChanged(float progress)20331         public void onPackageLoadingProgressChanged(float progress) {
20332             final PackageSetting ps;
20333             synchronized (mLock) {
20334                 ps = mSettings.getPackageLPr(mPackageName);
20335                 if (ps == null) {
20336                     return;
20337                 }
20338                 ps.setLoadingProgress(progress);
20339             }
20340         }
20341     }
20342 
getPackageSettingForUser(String packageName, int callingUid, int userId)20343     @Nullable PackageSetting getPackageSettingForUser(String packageName, int callingUid,
20344             int userId) {
20345         final PackageSetting ps;
20346         synchronized (mLock) {
20347             ps = mSettings.getPackageLPr(packageName);
20348             if (ps == null) {
20349                 Slog.w(TAG, "Failed to get package setting. Package " + packageName
20350                         + " is not installed");
20351                 return null;
20352             }
20353             if (!ps.getInstalled(userId)) {
20354                 Slog.w(TAG, "Failed to get package setting. Package " + packageName
20355                         + " is not installed for user " + userId);
20356                 return null;
20357             }
20358             if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
20359                 Slog.w(TAG, "Failed to get package setting. Package " + packageName
20360                         + " is not visible to the calling app");
20361                 return null;
20362             }
20363         }
20364         return ps;
20365     }
20366 
notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg)20367     private void notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg) {
20368       final PackageSetting pkgSetting = reconciledPkg.pkgSetting;
20369       final PackageInstalledInfo pkgInstalledInfo = reconciledPkg.installResult;
20370       final PackageRemovedInfo pkgRemovedInfo = pkgInstalledInfo.removedInfo;
20371 
20372       PackageChangeEvent pkgChangeEvent = new PackageChangeEvent();
20373       pkgChangeEvent.packageName = pkgSetting.pkg.getPackageName();
20374       pkgChangeEvent.version = pkgSetting.versionCode;
20375       pkgChangeEvent.lastUpdateTimeMillis = pkgSetting.lastUpdateTime;
20376       pkgChangeEvent.newInstalled = (pkgRemovedInfo == null || !pkgRemovedInfo.isUpdate);
20377       pkgChangeEvent.dataRemoved = (pkgRemovedInfo != null && pkgRemovedInfo.dataRemoved);
20378       pkgChangeEvent.isDeleted = false;
20379 
20380       notifyPackageChangeObservers(pkgChangeEvent);
20381     }
20382 
notifyPackageChangeObserversOnDelete(String packageName, long version)20383     private void notifyPackageChangeObserversOnDelete(String packageName, long version) {
20384       PackageChangeEvent pkgChangeEvent = new PackageChangeEvent();
20385       pkgChangeEvent.packageName = packageName;
20386       pkgChangeEvent.version = version;
20387       pkgChangeEvent.lastUpdateTimeMillis = 0L;
20388       pkgChangeEvent.newInstalled = false;
20389       pkgChangeEvent.dataRemoved = false;
20390       pkgChangeEvent.isDeleted = true;
20391 
20392       notifyPackageChangeObservers(pkgChangeEvent);
20393     }
20394 
notifyPackageChangeObservers(PackageChangeEvent event)20395     private void notifyPackageChangeObservers(PackageChangeEvent event) {
20396       try {
20397         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "notifyPackageChangeObservers");
20398         synchronized (mPackageChangeObservers) {
20399           for(IPackageChangeObserver observer : mPackageChangeObservers) {
20400             try {
20401               observer.onPackageChanged(event);
20402             } catch(RemoteException e) {
20403               Log.wtf(TAG, e);
20404             }
20405           }
20406         }
20407       } finally {
20408         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20409       }
20410     }
20411 
20412     /**
20413      * The set of data needed to successfully install the prepared package. This includes data that
20414      * will be used to scan and reconcile the package.
20415      */
20416     private static class PrepareResult {
20417         public final boolean replace;
20418         public final int scanFlags;
20419         public final int parseFlags;
20420         @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
20421         public final AndroidPackage existingPackage;
20422         public final ParsedPackage packageToScan;
20423         public final boolean clearCodeCache;
20424         public final boolean system;
20425         public final PackageSetting originalPs;
20426         public final PackageSetting disabledPs;
20427 
PrepareResult(boolean replace, int scanFlags, int parseFlags, AndroidPackage existingPackage, ParsedPackage packageToScan, boolean clearCodeCache, boolean system, PackageSetting originalPs, PackageSetting disabledPs)20428         private PrepareResult(boolean replace, int scanFlags,
20429                 int parseFlags, AndroidPackage existingPackage,
20430                 ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
20431                 PackageSetting originalPs, PackageSetting disabledPs) {
20432             this.replace = replace;
20433             this.scanFlags = scanFlags;
20434             this.parseFlags = parseFlags;
20435             this.existingPackage = existingPackage;
20436             this.packageToScan = packageToScan;
20437             this.clearCodeCache = clearCodeCache;
20438             this.system = system;
20439             this.originalPs = originalPs;
20440             this.disabledPs = disabledPs;
20441         }
20442     }
20443 
20444     private static class PrepareFailure extends PackageManagerException {
20445 
20446         public String conflictingPackage;
20447         public String conflictingPermission;
20448 
PrepareFailure(int error)20449         PrepareFailure(int error) {
20450             super(error, "Failed to prepare for install.");
20451         }
20452 
PrepareFailure(int error, String detailMessage)20453         PrepareFailure(int error, String detailMessage) {
20454             super(error, detailMessage);
20455         }
20456 
PrepareFailure(String message, Exception e)20457         PrepareFailure(String message, Exception e) {
20458             super(e instanceof PackageParserException
20459                     ? ((PackageParserException) e).error
20460                     : ((PackageManagerException) e).error,
20461                     ExceptionUtils.getCompleteMessage(message, e));
20462         }
20463 
conflictsWithExistingPermission(String conflictingPermission, String conflictingPackage)20464         PrepareFailure conflictsWithExistingPermission(String conflictingPermission,
20465                 String conflictingPackage) {
20466             this.conflictingPermission = conflictingPermission;
20467             this.conflictingPackage = conflictingPackage;
20468             return this;
20469         }
20470     }
20471 
doesSignatureMatchForPermissions(@onNull String sourcePackageName, @NonNull ParsedPackage parsedPackage, int scanFlags)20472     private boolean doesSignatureMatchForPermissions(@NonNull String sourcePackageName,
20473             @NonNull ParsedPackage parsedPackage, int scanFlags) {
20474         // If the defining package is signed with our cert, it's okay.  This
20475         // also includes the "updating the same package" case, of course.
20476         // "updating same package" could also involve key-rotation.
20477 
20478         final PackageSetting sourcePackageSetting;
20479         synchronized (mLock) {
20480             sourcePackageSetting = mSettings.getPackageLPr(sourcePackageName);
20481         }
20482 
20483         final SigningDetails sourceSigningDetails = (sourcePackageSetting == null
20484                 ? SigningDetails.UNKNOWN : sourcePackageSetting.getSigningDetails());
20485         final KeySetManagerService ksms = mSettings.getKeySetManagerService();
20486         if (sourcePackageName.equals(parsedPackage.getPackageName())
20487                 && (ksms.shouldCheckUpgradeKeySetLocked(
20488                 sourcePackageSetting, scanFlags))) {
20489             return ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage);
20490         } else {
20491 
20492             // in the event of signing certificate rotation, we need to see if the
20493             // package's certificate has rotated from the current one, or if it is an
20494             // older certificate with which the current is ok with sharing permissions
20495             if (sourceSigningDetails.checkCapability(
20496                     parsedPackage.getSigningDetails(),
20497                     PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
20498                 return true;
20499             } else if (parsedPackage.getSigningDetails().checkCapability(
20500                     sourceSigningDetails,
20501                     PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
20502                 // the scanned package checks out, has signing certificate rotation
20503                 // history, and is newer; bring it over
20504                 synchronized (mLock) {
20505                     sourcePackageSetting.signatures.mSigningDetails =
20506                             parsedPackage.getSigningDetails();
20507                 }
20508                 return true;
20509             } else {
20510                 return false;
20511             }
20512         }
20513     }
20514 
20515     /*
20516      * Cannot properly check CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS using CompatChanges
20517      * as this only works for packages that are installed
20518      *
20519      * TODO: Move logic for permission group compatibility into PermissionManagerService
20520      */
20521     @SuppressWarnings("AndroidFrameworkCompatChange")
cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage)20522     private static boolean cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage) {
20523         return parsedPackage.getTargetSdkVersion() >= Build.VERSION_CODES.S;
20524     }
20525 
20526     @GuardedBy("mInstallLock")
preparePackageLI(InstallArgs args, PackageInstalledInfo res)20527     private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
20528             throws PrepareFailure {
20529         final int installFlags = args.installFlags;
20530         final File tmpPackageFile = new File(args.getCodePath());
20531         final boolean onExternal = args.volumeUuid != null;
20532         final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
20533         final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
20534         final boolean virtualPreload =
20535                 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
20536         final boolean isRollback = args.installReason == PackageManager.INSTALL_REASON_ROLLBACK;
20537         @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
20538         if (args.move != null) {
20539             // moving a complete application; perform an initial scan on the new install location
20540             scanFlags |= SCAN_INITIAL;
20541         }
20542         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
20543             scanFlags |= SCAN_DONT_KILL_APP;
20544         }
20545         if (instantApp) {
20546             scanFlags |= SCAN_AS_INSTANT_APP;
20547         }
20548         if (fullApp) {
20549             scanFlags |= SCAN_AS_FULL_APP;
20550         }
20551         if (virtualPreload) {
20552             scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
20553         }
20554 
20555         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
20556 
20557         // Validity check
20558         if (instantApp && onExternal) {
20559             Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
20560             throw new PrepareFailure(PackageManager.INSTALL_FAILED_SESSION_INVALID);
20561         }
20562 
20563         // Retrieve PackageSettings and parse package
20564         @ParseFlags final int parseFlags = mDefParseFlags | ParsingPackageUtils.PARSE_CHATTY
20565                 | ParsingPackageUtils.PARSE_ENFORCE_CODE
20566                 | (onExternal ? ParsingPackageUtils.PARSE_EXTERNAL_STORAGE : 0);
20567 
20568         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
20569         final ParsedPackage parsedPackage;
20570         try (PackageParser2 pp = mInjector.getPreparingPackageParser()) {
20571             parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
20572             AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
20573         } catch (PackageParserException e) {
20574             throw new PrepareFailure("Failed parse during installPackageLI", e);
20575         } finally {
20576             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20577         }
20578 
20579         // Instant apps have several additional install-time checks.
20580         if (instantApp) {
20581             if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {
20582                 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
20583                                 + " does not target at least O");
20584                 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
20585                         "Instant app package must target at least O");
20586             }
20587             if (parsedPackage.getSharedUserId() != null) {
20588                 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
20589                         + " may not declare sharedUserId.");
20590                 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
20591                         "Instant app package may not declare a sharedUserId");
20592             }
20593         }
20594 
20595         if (parsedPackage.isStaticSharedLibrary()) {
20596             // Static shared libraries have synthetic package names
20597             renameStaticSharedLibraryPackage(parsedPackage);
20598 
20599             // No static shared libs on external storage
20600             if (onExternal) {
20601                 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
20602                 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
20603                         "Packages declaring static-shared libs cannot be updated");
20604             }
20605         }
20606 
20607         String pkgName = res.name = parsedPackage.getPackageName();
20608         if (parsedPackage.isTestOnly()) {
20609             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
20610                 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
20611             }
20612         }
20613 
20614         try {
20615             // either use what we've been given or parse directly from the APK
20616             if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
20617                 parsedPackage.setSigningDetails(args.signingDetails);
20618             } else {
20619                 parsedPackage.setSigningDetails(ParsingPackageUtils.getSigningDetails(
20620                         parsedPackage, false /* skipVerify */));
20621             }
20622         } catch (PackageParserException e) {
20623             throw new PrepareFailure("Failed collect during installPackageLI", e);
20624         }
20625 
20626         if (instantApp && parsedPackage.getSigningDetails().signatureSchemeVersion
20627                 < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
20628             Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
20629                     + " is not signed with at least APK Signature Scheme v2");
20630             throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
20631                     "Instant app package must be signed with APK Signature Scheme v2 or greater");
20632         }
20633 
20634         boolean systemApp = false;
20635         boolean replace = false;
20636         synchronized (mLock) {
20637             // Check if installing already existing package
20638             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
20639                 String oldName = mSettings.getRenamedPackageLPr(pkgName);
20640                 if (parsedPackage.getOriginalPackages().contains(oldName)
20641                         && mPackages.containsKey(oldName)) {
20642                     // This package is derived from an original package,
20643                     // and this device has been updating from that original
20644                     // name.  We must continue using the original name, so
20645                     // rename the new package here.
20646                     parsedPackage.setPackageName(oldName);
20647                     pkgName = parsedPackage.getPackageName();
20648                     replace = true;
20649                     if (DEBUG_INSTALL) {
20650                         Slog.d(TAG, "Replacing existing renamed package: oldName="
20651                                 + oldName + " pkgName=" + pkgName);
20652                     }
20653                 } else if (mPackages.containsKey(pkgName)) {
20654                     // This package, under its official name, already exists
20655                     // on the device; we should replace it.
20656                     replace = true;
20657                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
20658                 }
20659 
20660                 if (replace) {
20661                     // Prevent apps opting out from runtime permissions
20662                     AndroidPackage oldPackage = mPackages.get(pkgName);
20663                     final int oldTargetSdk = oldPackage.getTargetSdkVersion();
20664                     final int newTargetSdk = parsedPackage.getTargetSdkVersion();
20665                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
20666                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
20667                         throw new PrepareFailure(
20668                                 PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
20669                                 "Package " + parsedPackage.getPackageName()
20670                                         + " new target SDK " + newTargetSdk
20671                                         + " doesn't support runtime permissions but the old"
20672                                         + " target SDK " + oldTargetSdk + " does.");
20673                     }
20674                     // Prevent persistent apps from being updated
20675                     if (oldPackage.isPersistent()
20676                             && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {
20677                         throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,
20678                                 "Package " + oldPackage.getPackageName() + " is a persistent app. "
20679                                         + "Persistent apps are not updateable.");
20680                     }
20681                 }
20682             }
20683 
20684             PackageSetting ps = mSettings.getPackageLPr(pkgName);
20685             if (ps != null) {
20686                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
20687 
20688                 // Static shared libs have same package with different versions where
20689                 // we internally use a synthetic package name to allow multiple versions
20690                 // of the same package, therefore we need to compare signatures against
20691                 // the package setting for the latest library version.
20692                 PackageSetting signatureCheckPs = ps;
20693                 if (parsedPackage.isStaticSharedLibrary()) {
20694                     SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(parsedPackage);
20695                     if (libraryInfo != null) {
20696                         signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName());
20697                     }
20698                 }
20699 
20700                 // Quick validity check that we're signed correctly if updating;
20701                 // we'll check this again later when scanning, but we want to
20702                 // bail early here before tripping over redefined permissions.
20703                 final KeySetManagerService ksms = mSettings.getKeySetManagerService();
20704                 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
20705                     if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
20706                         throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
20707                                 + parsedPackage.getPackageName() + " upgrade keys do not match the "
20708                                 + "previously installed version");
20709                     }
20710                 } else {
20711                     try {
20712                         final boolean compareCompat = isCompatSignatureUpdateNeeded(parsedPackage);
20713                         final boolean compareRecover = isRecoverSignatureUpdateNeeded(
20714                                 parsedPackage);
20715                         // We don't care about disabledPkgSetting on install for now.
20716                         final boolean compatMatch = verifySignatures(signatureCheckPs, null,
20717                                 parsedPackage.getSigningDetails(), compareCompat, compareRecover,
20718                                 isRollback);
20719                         // The new KeySets will be re-added later in the scanning process.
20720                         if (compatMatch) {
20721                             synchronized (mLock) {
20722                                 ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName());
20723                             }
20724                         }
20725                     } catch (PackageManagerException e) {
20726                         throw new PrepareFailure(e.error, e.getMessage());
20727                     }
20728                 }
20729 
20730                 if (ps.pkg != null) {
20731                     systemApp = ps.pkg.isSystem();
20732                 }
20733                 res.origUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
20734             }
20735 
20736             final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups());
20737             for (int groupNum = 0; groupNum < numGroups; groupNum++) {
20738                 final ParsedPermissionGroup group =
20739                         parsedPackage.getPermissionGroups().get(groupNum);
20740                 final PermissionGroupInfo sourceGroup = getPermissionGroupInfo(group.getName(), 0);
20741 
20742                 if (sourceGroup != null
20743                         && cannotInstallWithBadPermissionGroups(parsedPackage)) {
20744                     final String sourcePackageName = sourceGroup.packageName;
20745 
20746                     if ((replace || !parsedPackage.getPackageName().equals(sourcePackageName))
20747                             && !doesSignatureMatchForPermissions(sourcePackageName, parsedPackage,
20748                             scanFlags)) {
20749                         EventLog.writeEvent(0x534e4554, "146211400", -1,
20750                                 parsedPackage.getPackageName());
20751 
20752                         throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP,
20753                                 "Package "
20754                                         + parsedPackage.getPackageName()
20755                                         + " attempting to redeclare permission group "
20756                                         + group.getName() + " already owned by "
20757                                         + sourcePackageName);
20758                     }
20759                 }
20760             }
20761 
20762            // TODO: Move logic for checking permission compatibility into PermissionManagerService
20763             final int N = ArrayUtils.size(parsedPackage.getPermissions());
20764             for (int i = N - 1; i >= 0; i--) {
20765                 final ParsedPermission perm = parsedPackage.getPermissions().get(i);
20766                 final Permission bp = mPermissionManager.getPermissionTEMP(perm.getName());
20767 
20768                 // Don't allow anyone but the system to define ephemeral permissions.
20769                 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
20770                         && !systemApp) {
20771                     Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName()
20772                             + " attempting to delcare ephemeral permission "
20773                             + perm.getName() + "; Removing ephemeral.");
20774                     perm.setProtectionLevel(perm.getProtectionLevel() & ~PermissionInfo.PROTECTION_FLAG_INSTANT);
20775                 }
20776 
20777                 // Check whether the newly-scanned package wants to define an already-defined perm
20778                 if (bp != null) {
20779                     final String sourcePackageName = bp.getPackageName();
20780 
20781                     if (!doesSignatureMatchForPermissions(sourcePackageName, parsedPackage,
20782                             scanFlags)) {
20783                         // If the owning package is the system itself, we log but allow
20784                         // install to proceed; we fail the install on all other permission
20785                         // redefinitions.
20786                         if (!sourcePackageName.equals("android")) {
20787                             throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
20788                                     + parsedPackage.getPackageName()
20789                                     + " attempting to redeclare permission "
20790                                     + perm.getName() + " already owned by "
20791                                     + sourcePackageName)
20792                                     .conflictsWithExistingPermission(perm.getName(),
20793                                             sourcePackageName);
20794                         } else {
20795                             Slog.w(TAG, "Package " + parsedPackage.getPackageName()
20796                                     + " attempting to redeclare system permission "
20797                                     + perm.getName() + "; ignoring new declaration");
20798                             parsedPackage.removePermission(i);
20799                         }
20800                     } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) {
20801                         // Prevent apps to change protection level to dangerous from any other
20802                         // type as this would allow a privilege escalation where an app adds a
20803                         // normal/signature permission in other app's group and later redefines
20804                         // it as dangerous leading to the group auto-grant.
20805                         if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE)
20806                                 == PermissionInfo.PROTECTION_DANGEROUS) {
20807                             if (bp != null && !bp.isRuntime()) {
20808                                 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
20809                                         + " trying to change a non-runtime permission "
20810                                         + perm.getName()
20811                                         + " to runtime; keeping old protection level");
20812                                 perm.setProtectionLevel(bp.getProtectionLevel());
20813                             }
20814                         }
20815                     }
20816                 }
20817 
20818                 if (perm.getGroup() != null
20819                         && cannotInstallWithBadPermissionGroups(parsedPackage)) {
20820                     boolean isPermGroupDefinedByPackage = false;
20821                     for (int groupNum = 0; groupNum < numGroups; groupNum++) {
20822                         if (parsedPackage.getPermissionGroups().get(groupNum).getName()
20823                                 .equals(perm.getGroup())) {
20824                             isPermGroupDefinedByPackage = true;
20825                             break;
20826                         }
20827                     }
20828 
20829                     if (!isPermGroupDefinedByPackage) {
20830                         final PermissionGroupInfo sourceGroup =
20831                                 getPermissionGroupInfo(perm.getGroup(), 0);
20832 
20833                         if (sourceGroup == null) {
20834                             EventLog.writeEvent(0x534e4554, "146211400", -1,
20835                                     parsedPackage.getPackageName());
20836 
20837                             throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP,
20838                                     "Package "
20839                                             + parsedPackage.getPackageName()
20840                                             + " attempting to declare permission "
20841                                             + perm.getName() + " in non-existing group "
20842                                             + perm.getGroup());
20843                         } else {
20844                             String groupSourcePackageName = sourceGroup.packageName;
20845 
20846                             if (!PLATFORM_PACKAGE_NAME.equals(groupSourcePackageName)
20847                                     && !doesSignatureMatchForPermissions(groupSourcePackageName,
20848                                     parsedPackage, scanFlags)) {
20849                                 EventLog.writeEvent(0x534e4554, "146211400", -1,
20850                                         parsedPackage.getPackageName());
20851 
20852                                 throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP,
20853                                         "Package "
20854                                                 + parsedPackage.getPackageName()
20855                                                 + " attempting to declare permission "
20856                                                 + perm.getName() + " in group "
20857                                                 + perm.getGroup() + " owned by package "
20858                                                 + groupSourcePackageName
20859                                                 + " with incompatible certificate");
20860                             }
20861                         }
20862                     }
20863                 }
20864             }
20865         }
20866 
20867         if (systemApp) {
20868             if (onExternal) {
20869                 // Abort update; system app can't be replaced with app on sdcard
20870                 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
20871                         "Cannot install updates to system apps on sdcard");
20872             } else if (instantApp) {
20873                 // Abort update; system app can't be replaced with an instant app
20874                 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
20875                         "Cannot update a system app with an instant app");
20876             }
20877         }
20878 
20879         if (args.move != null) {
20880             // We did an in-place move, so dex is ready to roll
20881             scanFlags |= SCAN_NO_DEX;
20882             scanFlags |= SCAN_MOVE;
20883 
20884             synchronized (mLock) {
20885                 final PackageSetting ps = mSettings.getPackageLPr(pkgName);
20886                 if (ps == null) {
20887                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
20888                             "Missing settings for moved package " + pkgName);
20889                 }
20890 
20891                 // We moved the entire application as-is, so bring over the
20892                 // previously derived ABI information.
20893                 parsedPackage.setPrimaryCpuAbi(ps.primaryCpuAbiString)
20894                         .setSecondaryCpuAbi(ps.secondaryCpuAbiString);
20895             }
20896 
20897         } else {
20898             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
20899             scanFlags |= SCAN_NO_DEX;
20900 
20901             try {
20902                 PackageSetting pkgSetting;
20903                 synchronized (mLock) {
20904                     pkgSetting = mSettings.getPackageLPr(pkgName);
20905                 }
20906                 boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null
20907                         && pkgSetting.getPkgState().isUpdatedSystemApp();
20908                 final String abiOverride = deriveAbiOverride(args.abiOverride);
20909                 AndroidPackage oldPackage = mPackages.get(pkgName);
20910                 boolean isUpdatedSystemAppInferred = oldPackage != null && oldPackage.isSystem();
20911                 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
20912                         derivedAbi = mInjector.getAbiHelper().derivePackageAbi(parsedPackage,
20913                         isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
20914                         abiOverride, mAppLib32InstallDir);
20915                 derivedAbi.first.applyTo(parsedPackage);
20916                 derivedAbi.second.applyTo(parsedPackage);
20917             } catch (PackageManagerException pme) {
20918                 Slog.e(TAG, "Error deriving application ABI", pme);
20919                 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
20920                         "Error deriving application ABI: " + pme.getMessage());
20921             }
20922         }
20923 
20924         if (!args.doRename(res.returnCode, parsedPackage)) {
20925             throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
20926         }
20927 
20928         try {
20929             setUpFsVerityIfPossible(parsedPackage);
20930         } catch (InstallerException | IOException | DigestException | NoSuchAlgorithmException e) {
20931             throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
20932                     "Failed to set up verity: " + e);
20933         }
20934 
20935         final PackageFreezer freezer =
20936                 freezePackageForInstall(pkgName, installFlags, "installPackageLI");
20937         boolean shouldCloseFreezerBeforeReturn = true;
20938         try {
20939             final AndroidPackage existingPackage;
20940             String renamedPackage = null;
20941             boolean sysPkg = false;
20942             int targetScanFlags = scanFlags;
20943             int targetParseFlags = parseFlags;
20944             final PackageSetting ps;
20945             final PackageSetting disabledPs;
20946             if (replace) {
20947                 if (parsedPackage.isStaticSharedLibrary()) {
20948                     // Static libs have a synthetic package name containing the version
20949                     // and cannot be updated as an update would get a new package name,
20950                     // unless this is installed from adb which is useful for development.
20951                     AndroidPackage existingPkg = mPackages.get(parsedPackage.getPackageName());
20952                     if (existingPkg != null
20953                             && (installFlags & PackageManager.INSTALL_FROM_ADB) == 0) {
20954                         throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
20955                                 "Packages declaring "
20956                                         + "static-shared libs cannot be updated");
20957                     }
20958                 }
20959 
20960                 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
20961 
20962                 final AndroidPackage oldPackage;
20963                 final String pkgName11 = parsedPackage.getPackageName();
20964                 final int[] allUsers;
20965                 final int[] installedUsers;
20966                 final int[] uninstalledUsers;
20967 
20968                 synchronized (mLock) {
20969                     oldPackage = mPackages.get(pkgName11);
20970                     existingPackage = oldPackage;
20971                     if (DEBUG_INSTALL) {
20972                         Slog.d(TAG,
20973                                 "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
20974                     }
20975 
20976                     ps = mSettings.getPackageLPr(pkgName11);
20977                     disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
20978 
20979                     // verify signatures are valid
20980                     final KeySetManagerService ksms = mSettings.getKeySetManagerService();
20981                     if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
20982                         if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) {
20983                             throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
20984                                     "New package not signed by keys specified by upgrade-keysets: "
20985                                             + pkgName11);
20986                         }
20987                     } else {
20988                         SigningDetails parsedPkgSigningDetails = parsedPackage.getSigningDetails();
20989                         SigningDetails oldPkgSigningDetails = oldPackage.getSigningDetails();
20990                         // default to original signature matching
20991                         if (!parsedPkgSigningDetails.checkCapability(oldPkgSigningDetails,
20992                                 SigningDetails.CertCapabilities.INSTALLED_DATA)
20993                                 && !oldPkgSigningDetails.checkCapability(parsedPkgSigningDetails,
20994                                 SigningDetails.CertCapabilities.ROLLBACK)) {
20995                             // Allow the update to proceed if this is a rollback and the parsed
20996                             // package's current signing key is the current signer or in the lineage
20997                             // of the old package; this allows a rollback to a previously installed
20998                             // version after an app's signing key has been rotated without requiring
20999                             // the rollback capability on the previous signing key.
21000                             if (!isRollback || !oldPkgSigningDetails.hasAncestorOrSelf(
21001                                     parsedPkgSigningDetails)) {
21002                                 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
21003                                         "New package has a different signature: " + pkgName11);
21004                             }
21005                         }
21006                     }
21007 
21008                     // don't allow a system upgrade unless the upgrade hash matches
21009                     if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) {
21010                         final byte[] digestBytes;
21011                         try {
21012                             final MessageDigest digest = MessageDigest.getInstance("SHA-512");
21013                             updateDigest(digest, new File(parsedPackage.getBaseApkPath()));
21014                             if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) {
21015                                 for (String path : parsedPackage.getSplitCodePaths()) {
21016                                     updateDigest(digest, new File(path));
21017                                 }
21018                             }
21019                             digestBytes = digest.digest();
21020                         } catch (NoSuchAlgorithmException | IOException e) {
21021                             throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
21022                                     "Could not compute hash: " + pkgName11);
21023                         }
21024                         if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) {
21025                             throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
21026                                     "New package fails restrict-update check: " + pkgName11);
21027                         }
21028                         // retain upgrade restriction
21029                         parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash());
21030                     }
21031 
21032                     // Check for shared user id changes
21033                     String invalidPackageName = null;
21034                     if (!Objects.equals(oldPackage.getSharedUserId(),
21035                             parsedPackage.getSharedUserId())) {
21036                         invalidPackageName = parsedPackage.getPackageName();
21037                     }
21038 
21039                     if (invalidPackageName != null) {
21040                         throw new PrepareFailure(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
21041                                 "Package " + invalidPackageName + " tried to change user "
21042                                         + oldPackage.getSharedUserId());
21043                     }
21044 
21045                     // In case of rollback, remember per-user/profile install state
21046                     allUsers = mUserManager.getUserIds();
21047                     installedUsers = ps.queryInstalledUsers(allUsers, true);
21048                     uninstalledUsers = ps.queryInstalledUsers(allUsers, false);
21049 
21050 
21051                     // don't allow an upgrade from full to ephemeral
21052                     if (isInstantApp) {
21053                         if (args.user == null || args.user.getIdentifier() == UserHandle.USER_ALL) {
21054                             for (int currentUser : allUsers) {
21055                                 if (!ps.getInstantApp(currentUser)) {
21056                                     // can't downgrade from full to instant
21057                                     Slog.w(TAG,
21058                                             "Can't replace full app with instant app: " + pkgName11
21059                                                     + " for user: " + currentUser);
21060                                     throw new PrepareFailure(
21061                                             PackageManager.INSTALL_FAILED_SESSION_INVALID);
21062                                 }
21063                             }
21064                         } else if (!ps.getInstantApp(args.user.getIdentifier())) {
21065                             // can't downgrade from full to instant
21066                             Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11
21067                                     + " for user: " + args.user.getIdentifier());
21068                             throw new PrepareFailure(
21069                                     PackageManager.INSTALL_FAILED_SESSION_INVALID);
21070                         }
21071                     }
21072                 }
21073 
21074                 // Update what is removed
21075                 res.removedInfo = new PackageRemovedInfo(this);
21076                 res.removedInfo.uid = oldPackage.getUid();
21077                 res.removedInfo.removedPackage = oldPackage.getPackageName();
21078                 res.removedInfo.installerPackageName = ps.installSource.installerPackageName;
21079                 res.removedInfo.isStaticSharedLib = parsedPackage.getStaticSharedLibName() != null;
21080                 res.removedInfo.isUpdate = true;
21081                 res.removedInfo.origUsers = installedUsers;
21082                 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
21083                 for (int i = 0; i < installedUsers.length; i++) {
21084                     final int userId = installedUsers[i];
21085                     res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
21086                 }
21087                 res.removedInfo.uninstallReasons = new SparseArray<>(uninstalledUsers.length);
21088                 for (int i = 0; i < uninstalledUsers.length; i++) {
21089                     final int userId = uninstalledUsers[i];
21090                     res.removedInfo.uninstallReasons.put(userId, ps.getUninstallReason(userId));
21091                 }
21092 
21093                 sysPkg = oldPackage.isSystem();
21094                 if (sysPkg) {
21095                     // Set the system/privileged/oem/vendor/product flags as needed
21096                     final boolean privileged = oldPackage.isPrivileged();
21097                     final boolean oem = oldPackage.isOem();
21098                     final boolean vendor = oldPackage.isVendor();
21099                     final boolean product = oldPackage.isProduct();
21100                     final boolean odm = oldPackage.isOdm();
21101                     final boolean systemExt = oldPackage.isSystemExt();
21102                     final @ParseFlags int systemParseFlags = parseFlags;
21103                     final @ScanFlags int systemScanFlags = scanFlags
21104                             | SCAN_AS_SYSTEM
21105                             | (privileged ? SCAN_AS_PRIVILEGED : 0)
21106                             | (oem ? SCAN_AS_OEM : 0)
21107                             | (vendor ? SCAN_AS_VENDOR : 0)
21108                             | (product ? SCAN_AS_PRODUCT : 0)
21109                             | (odm ? SCAN_AS_ODM : 0)
21110                             | (systemExt ? SCAN_AS_SYSTEM_EXT : 0);
21111 
21112                     if (DEBUG_INSTALL) {
21113                         Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
21114                                 + ", old=" + oldPackage);
21115                     }
21116                     res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
21117                     targetParseFlags = systemParseFlags;
21118                     targetScanFlags = systemScanFlags;
21119                 } else { // non system replace
21120                     replace = true;
21121                     if (DEBUG_INSTALL) {
21122                         Slog.d(TAG,
21123                                 "replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
21124                                         + oldPackage);
21125                     }
21126                 }
21127             } else { // new package install
21128                 ps = null;
21129                 disabledPs = null;
21130                 replace = false;
21131                 existingPackage = null;
21132                 // Remember this for later, in case we need to rollback this install
21133                 String pkgName1 = parsedPackage.getPackageName();
21134 
21135                 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage);
21136 
21137                 // TODO(patb): MOVE TO RECONCILE
21138                 synchronized (mLock) {
21139                     renamedPackage = mSettings.getRenamedPackageLPr(pkgName1);
21140                     if (renamedPackage != null) {
21141                         // A package with the same name is already installed, though
21142                         // it has been renamed to an older name.  The package we
21143                         // are trying to install should be installed as an update to
21144                         // the existing one, but that has not been requested, so bail.
21145                         throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
21146                                 "Attempt to re-install " + pkgName1
21147                                         + " without first uninstalling package running as "
21148                                         + renamedPackage);
21149                     }
21150                     if (mPackages.containsKey(pkgName1)) {
21151                         // Don't allow installation over an existing package with the same name.
21152                         throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
21153                                 "Attempt to re-install " + pkgName1
21154                                         + " without first uninstalling.");
21155                     }
21156                 }
21157             }
21158             // we're passing the freezer back to be closed in a later phase of install
21159             shouldCloseFreezerBeforeReturn = false;
21160 
21161             return new PrepareResult(replace, targetScanFlags, targetParseFlags,
21162                     existingPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
21163                     ps, disabledPs);
21164         } finally {
21165             res.freezer = freezer;
21166             if (shouldCloseFreezerBeforeReturn) {
21167                 freezer.close();
21168             }
21169         }
21170     }
21171 
21172     /**
21173      * Set up fs-verity for the given package if possible.  This requires a feature flag of system
21174      * property to be enabled only if the kernel supports fs-verity.
21175      *
21176      * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
21177      * kernel patches). In normal mode, all file format can be supported.
21178      */
setUpFsVerityIfPossible(AndroidPackage pkg)21179     private void setUpFsVerityIfPossible(AndroidPackage pkg) throws InstallerException,
21180             PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
21181         final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled();
21182         final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled();
21183         if (!standardMode && !legacyMode) {
21184             return;
21185         }
21186 
21187         if (isIncrementalPath(pkg.getPath()) && IncrementalManager.getVersion()
21188                 < IncrementalManager.MIN_VERSION_TO_SUPPORT_FSVERITY) {
21189             return;
21190         }
21191 
21192         // Collect files we care for fs-verity setup.
21193         ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
21194         if (legacyMode) {
21195             synchronized (mLock) {
21196                 final PackageSetting ps = mSettings.getPackageLPr(pkg.getPackageName());
21197                 if (ps != null && ps.isPrivileged()) {
21198                     fsverityCandidates.put(pkg.getBaseApkPath(), null);
21199                     if (pkg.getSplitCodePaths() != null) {
21200                         for (String splitPath : pkg.getSplitCodePaths()) {
21201                             fsverityCandidates.put(splitPath, null);
21202                         }
21203                     }
21204                 }
21205             }
21206         } else {
21207             // NB: These files will become only accessible if the signing key is loaded in kernel's
21208             // .fs-verity keyring.
21209             fsverityCandidates.put(pkg.getBaseApkPath(),
21210                     VerityUtils.getFsveritySignatureFilePath(pkg.getBaseApkPath()));
21211 
21212             final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(
21213                     pkg.getBaseApkPath());
21214             if (new File(dmPath).exists()) {
21215                 fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
21216             }
21217 
21218             if (pkg.getSplitCodePaths() != null) {
21219                 for (String path : pkg.getSplitCodePaths()) {
21220                     fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path));
21221 
21222                     final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path);
21223                     if (new File(splitDmPath).exists()) {
21224                         fsverityCandidates.put(splitDmPath,
21225                                 VerityUtils.getFsveritySignatureFilePath(splitDmPath));
21226                     }
21227                 }
21228             }
21229         }
21230 
21231         for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
21232             final String filePath = entry.getKey();
21233             final String signaturePath = entry.getValue();
21234 
21235             if (!legacyMode) {
21236                 // fs-verity is optional for now.  Only set up if signature is provided.
21237                 if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) {
21238                     try {
21239                         VerityUtils.setUpFsverity(filePath, signaturePath);
21240                     } catch (IOException e) {
21241                         throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
21242                                 "Failed to enable fs-verity: " + e);
21243                     }
21244                 }
21245                 continue;
21246             }
21247 
21248             // In legacy mode, fs-verity can only be enabled by process with CAP_SYS_ADMIN.
21249             final VerityUtils.SetupResult result = VerityUtils.generateApkVeritySetupData(filePath);
21250             if (result.isOk()) {
21251                 if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling verity to " + filePath);
21252                 final FileDescriptor fd = result.getUnownedFileDescriptor();
21253                 try {
21254                     final byte[] rootHash = VerityUtils.generateApkVerityRootHash(filePath);
21255                     try {
21256                         // A file may already have fs-verity, e.g. when reused during a split
21257                         // install. If the measurement succeeds, no need to attempt to set up.
21258                         mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
21259                     } catch (InstallerException e) {
21260                         mInstaller.installApkVerity(filePath, fd, result.getContentSize());
21261                         mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
21262                     }
21263                 } finally {
21264                     IoUtils.closeQuietly(fd);
21265                 }
21266             } else if (result.isFailed()) {
21267                 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
21268                         "Failed to generate verity");
21269             }
21270         }
21271     }
21272 
isExternal(PackageSetting ps)21273     private static boolean isExternal(PackageSetting ps) {
21274         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
21275     }
21276 
isSystemApp(PackageSetting ps)21277     private static boolean isSystemApp(PackageSetting ps) {
21278         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
21279     }
21280 
isUpdatedSystemApp(PackageSetting ps)21281     private static boolean isUpdatedSystemApp(PackageSetting ps) {
21282         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
21283     }
21284 
getSettingsVersionForPackage(AndroidPackage pkg)21285     private VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) {
21286         if (pkg.isExternalStorage()) {
21287             if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
21288                 return mSettings.getExternalVersion();
21289             } else {
21290                 return mSettings.findOrCreateVersion(pkg.getVolumeUuid());
21291             }
21292         } else {
21293             return mSettings.getInternalVersion();
21294         }
21295     }
21296 
21297     @Override
deletePackageAsUser(String packageName, int versionCode, IPackageDeleteObserver observer, int userId, int flags)21298     public void deletePackageAsUser(String packageName, int versionCode,
21299             IPackageDeleteObserver observer, int userId, int flags) {
21300         deletePackageVersioned(new VersionedPackage(packageName, versionCode),
21301                 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
21302     }
21303 
21304     @Override
deleteExistingPackageAsUser(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId)21305     public void deleteExistingPackageAsUser(VersionedPackage versionedPackage,
21306             final IPackageDeleteObserver2 observer, final int userId) {
21307         mContext.enforceCallingOrSelfPermission(
21308                 android.Manifest.permission.DELETE_PACKAGES, null);
21309         Preconditions.checkNotNull(versionedPackage);
21310         Preconditions.checkNotNull(observer);
21311         final String packageName = versionedPackage.getPackageName();
21312         final long versionCode = versionedPackage.getLongVersionCode();
21313 
21314         int installedForUsersCount = 0;
21315         synchronized (mLock) {
21316             // Normalize package name to handle renamed packages and static libs
21317             final String internalPkgName = resolveInternalPackageNameLPr(packageName, versionCode);
21318             final PackageSetting ps = mSettings.getPackageLPr(internalPkgName);
21319             if (ps != null) {
21320                 int[] installedUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
21321                 installedForUsersCount = installedUsers.length;
21322             }
21323         }
21324 
21325         if (installedForUsersCount > 1) {
21326             deletePackageVersionedInternal(versionedPackage, observer, userId, 0, true);
21327         } else {
21328             try {
21329                 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_INTERNAL_ERROR,
21330                         null);
21331             } catch (RemoteException re) {
21332             }
21333         }
21334     }
21335 
21336     @Override
deletePackageVersioned(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags)21337     public void deletePackageVersioned(VersionedPackage versionedPackage,
21338             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
21339         deletePackageVersionedInternal(versionedPackage, observer, userId, deleteFlags, false);
21340     }
21341 
deletePackageVersionedInternal(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags, final boolean allowSilentUninstall)21342     private void deletePackageVersionedInternal(VersionedPackage versionedPackage,
21343             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags,
21344             final boolean allowSilentUninstall) {
21345         final int callingUid = Binder.getCallingUid();
21346         mContext.enforceCallingOrSelfPermission(
21347                 android.Manifest.permission.DELETE_PACKAGES, null);
21348         final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
21349         Preconditions.checkNotNull(versionedPackage);
21350         Preconditions.checkNotNull(observer);
21351         Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
21352                 PackageManager.VERSION_CODE_HIGHEST,
21353                 Long.MAX_VALUE, "versionCode must be >= -1");
21354 
21355         final String packageName = versionedPackage.getPackageName();
21356         final long versionCode = versionedPackage.getLongVersionCode();
21357         final String internalPackageName;
21358 
21359         try {
21360             if (mInjector.getLocalService(ActivityTaskManagerInternal.class)
21361                     .isBaseOfLockedTask(packageName)) {
21362                 observer.onPackageDeleted(
21363                         packageName, PackageManager.DELETE_FAILED_APP_PINNED, null);
21364                 EventLog.writeEvent(0x534e4554, "127605586", -1, "");
21365                 return;
21366             }
21367         } catch (RemoteException e) {
21368             e.rethrowFromSystemServer();
21369         }
21370 
21371         synchronized (mLock) {
21372             // Normalize package name to handle renamed packages and static libs
21373             internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
21374         }
21375 
21376         final int uid = Binder.getCallingUid();
21377         if (!isOrphaned(internalPackageName)
21378                 && !allowSilentUninstall
21379                 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
21380             mHandler.post(() -> {
21381                 try {
21382                     final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
21383                     intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
21384                     intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
21385                     observer.onUserActionRequired(intent);
21386                 } catch (RemoteException re) {
21387                 }
21388             });
21389             return;
21390         }
21391         final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
21392         final int[] users = deleteAllUsers ? mUserManager.getUserIds() : new int[]{userId};
21393         if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
21394             mContext.enforceCallingOrSelfPermission(
21395                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
21396                     "deletePackage for user " + userId);
21397         }
21398 
21399         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
21400             mHandler.post(() -> {
21401                 try {
21402                     observer.onPackageDeleted(packageName,
21403                             PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
21404                 } catch (RemoteException re) {
21405                 }
21406             });
21407             return;
21408         }
21409 
21410         if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
21411             mHandler.post(() -> {
21412                 try {
21413                     observer.onPackageDeleted(packageName,
21414                             PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
21415                 } catch (RemoteException re) {
21416                 }
21417             });
21418             return;
21419         }
21420 
21421         if (DEBUG_REMOVE) {
21422             Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
21423                     + " deleteAllUsers: " + deleteAllUsers + " version="
21424                     + (versionCode == PackageManager.VERSION_CODE_HIGHEST
21425                     ? "VERSION_CODE_HIGHEST" : versionCode));
21426         }
21427         // Queue up an async operation since the package deletion may take a little while.
21428         mHandler.post(() -> {
21429             int returnCode;
21430             final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
21431             boolean doDeletePackage = true;
21432             if (ps != null) {
21433                 final boolean targetIsInstantApp =
21434                         ps.getInstantApp(UserHandle.getUserId(callingUid));
21435                 doDeletePackage = !targetIsInstantApp
21436                         || canViewInstantApps;
21437             }
21438             if (doDeletePackage) {
21439                 if (!deleteAllUsers) {
21440                     returnCode = deletePackageX(internalPackageName, versionCode,
21441                             userId, deleteFlags, false /*removedBySystem*/);
21442                 } else {
21443                     int[] blockUninstallUserIds = getBlockUninstallForUsers(
21444                             internalPackageName, users);
21445                     // If nobody is blocking uninstall, proceed with delete for all users
21446                     if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
21447                         returnCode = deletePackageX(internalPackageName, versionCode,
21448                                 userId, deleteFlags, false /*removedBySystem*/);
21449                     } else {
21450                         // Otherwise uninstall individually for users with blockUninstalls=false
21451                         final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
21452                         for (int userId1 : users) {
21453                             if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) {
21454                                 returnCode = deletePackageX(internalPackageName, versionCode,
21455                                         userId1, userFlags, false /*removedBySystem*/);
21456                                 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
21457                                     Slog.w(TAG, "Package delete failed for user " + userId1
21458                                             + ", returnCode " + returnCode);
21459                                 }
21460                             }
21461                         }
21462                         // The app has only been marked uninstalled for certain users.
21463                         // We still need to report that delete was blocked
21464                         returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
21465                     }
21466                 }
21467             } else {
21468                 returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
21469             }
21470             try {
21471                 observer.onPackageDeleted(packageName, returnCode, null);
21472             } catch (RemoteException e) {
21473                 Log.i(TAG, "Observer no longer exists.");
21474             } //end catch
21475             notifyPackageChangeObserversOnDelete(packageName, versionCode);
21476         });
21477     }
21478 
resolveExternalPackageNameLPr(AndroidPackage pkg)21479     private String resolveExternalPackageNameLPr(AndroidPackage pkg) {
21480         return mComputer.resolveExternalPackageNameLPr(pkg);
21481     }
21482 
21483     @GuardedBy("mLock")
resolveInternalPackageNameLPr(String packageName, long versionCode)21484     private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
21485         return mComputer.resolveInternalPackageNameLPr(packageName, versionCode);
21486     }
21487 
isCallerVerifier(int callingUid)21488     boolean isCallerVerifier(int callingUid) {
21489         final int callingUserId = UserHandle.getUserId(callingUid);
21490         return mRequiredVerifierPackage != null &&
21491                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
21492     }
21493 
isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName)21494     private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
21495         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
21496               || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
21497             return true;
21498         }
21499         final int callingUserId = UserHandle.getUserId(callingUid);
21500         // If the caller installed the pkgName, then allow it to silently uninstall.
21501         if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
21502             return true;
21503         }
21504 
21505         // Allow package verifier to silently uninstall.
21506         if (mRequiredVerifierPackage != null &&
21507                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
21508             return true;
21509         }
21510 
21511         // Allow package uninstaller to silently uninstall.
21512         if (mRequiredUninstallerPackage != null &&
21513                 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
21514             return true;
21515         }
21516 
21517         // Allow storage manager to silently uninstall.
21518         if (mStorageManagerPackage != null &&
21519                 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
21520             return true;
21521         }
21522 
21523         // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
21524         // uninstall for device owner provisioning.
21525         if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
21526                 == PERMISSION_GRANTED) {
21527             return true;
21528         }
21529 
21530         return false;
21531     }
21532 
getBlockUninstallForUsers(String packageName, int[] userIds)21533     private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
21534         int[] result = EMPTY_INT_ARRAY;
21535         for (int userId : userIds) {
21536             if (getBlockUninstallForUser(packageName, userId)) {
21537                 result = ArrayUtils.appendInt(result, userId);
21538             }
21539         }
21540         return result;
21541     }
21542 
21543     @Override
isPackageDeviceAdminOnAnyUser(String packageName)21544     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
21545         final int callingUid = Binder.getCallingUid();
21546         if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
21547                 != PERMISSION_GRANTED) {
21548             EventLog.writeEvent(0x534e4554, "128599183", -1, "");
21549             throw new SecurityException(android.Manifest.permission.MANAGE_USERS
21550                     + " permission is required to call this API");
21551         }
21552         if (getInstantAppPackageName(callingUid) != null
21553                 && !isCallerSameApp(packageName, callingUid)) {
21554             return false;
21555         }
21556         return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
21557     }
21558 
isPackageDeviceAdmin(String packageName, int userId)21559     private boolean isPackageDeviceAdmin(String packageName, int userId) {
21560         final IDevicePolicyManager dpm = getDevicePolicyManager();
21561         try {
21562             if (dpm != null) {
21563                 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
21564                         /* callingUserOnly =*/ false);
21565                 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
21566                         : deviceOwnerComponentName.getPackageName();
21567                 // Does the package contains the device owner?
21568                 // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
21569                 // this check is probably not needed, since DO should be registered as a device
21570                 // admin on some user too. (Original bug for this: b/17657954)
21571                 if (packageName.equals(deviceOwnerPackageName)) {
21572                     return true;
21573                 }
21574                 // Does it contain a device admin for any user?
21575                 int[] users;
21576                 if (userId == UserHandle.USER_ALL) {
21577                     users = mUserManager.getUserIds();
21578                 } else {
21579                     users = new int[]{userId};
21580                 }
21581                 for (int i = 0; i < users.length; ++i) {
21582                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
21583                         return true;
21584                     }
21585                 }
21586             }
21587         } catch (RemoteException e) {
21588         }
21589         return false;
21590     }
21591 
21592     /** Returns the device policy manager interface. */
getDevicePolicyManager()21593     private IDevicePolicyManager getDevicePolicyManager() {
21594         if (mDevicePolicyManager == null) {
21595             // No need to synchronize; worst-case scenario it will be fetched twice.
21596             mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
21597                             ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
21598         }
21599         return mDevicePolicyManager;
21600     }
21601 
shouldKeepUninstalledPackageLPr(String packageName)21602     private boolean shouldKeepUninstalledPackageLPr(String packageName) {
21603         return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
21604     }
21605 
21606     /**
21607      *  This method is an internal method that could be get invoked either
21608      *  to delete an installed package or to clean up a failed installation.
21609      *  After deleting an installed package, a broadcast is sent to notify any
21610      *  listeners that the package has been removed. For cleaning up a failed
21611      *  installation, the broadcast is not necessary since the package's
21612      *  installation wouldn't have sent the initial broadcast either
21613      *  The key steps in deleting a package are
21614      *  deleting the package information in internal structures like mPackages,
21615      *  deleting the packages base directories through installd
21616      *  updating mSettings to reflect current status
21617      *  persisting settings for later use
21618      *  sending a broadcast if necessary
21619      *
21620      *  @param removedBySystem A boolean to indicate the package was removed automatically without
21621      *                         the user-initiated action.
21622      */
deletePackageX(String packageName, long versionCode, int userId, int deleteFlags, boolean removedBySystem)21623     int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags,
21624             boolean removedBySystem) {
21625         final PackageRemovedInfo info = new PackageRemovedInfo(this);
21626         final boolean res;
21627 
21628         final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
21629                 ? UserHandle.USER_ALL : userId;
21630 
21631         if (isPackageDeviceAdmin(packageName, removeUser)) {
21632             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
21633             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
21634         }
21635 
21636         final PackageSetting uninstalledPs;
21637         final PackageSetting disabledSystemPs;
21638         final AndroidPackage pkg;
21639 
21640         // for the uninstall-updates case and restricted profiles, remember the per-
21641         // user handle installed state
21642         int[] allUsers;
21643         final int freezeUser;
21644         final SparseArray<TempUserState> priorUserStates;
21645         /** enabled state of the uninstalled application */
21646         synchronized (mLock) {
21647             uninstalledPs = mSettings.getPackageLPr(packageName);
21648             if (uninstalledPs == null) {
21649                 Slog.w(TAG, "Not removing non-existent package " + packageName);
21650                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
21651             }
21652 
21653             if (versionCode != PackageManager.VERSION_CODE_HIGHEST
21654                     && uninstalledPs.versionCode != versionCode) {
21655                 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
21656                         + uninstalledPs.versionCode + " != " + versionCode);
21657                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
21658             }
21659 
21660             if (isSystemApp(uninstalledPs)) {
21661                 UserInfo userInfo = mUserManager.getUserInfo(userId);
21662                 if (userInfo == null || !userInfo.isAdmin()) {
21663                     Slog.w(TAG, "Not removing package " + packageName
21664                             + " as only admin user may downgrade system apps");
21665                     EventLog.writeEvent(0x534e4554, "170646036", -1, packageName);
21666                     return PackageManager.DELETE_FAILED_USER_RESTRICTED;
21667                 }
21668             }
21669 
21670             disabledSystemPs = mSettings.getDisabledSystemPkgLPr(packageName);
21671             // Static shared libs can be declared by any package, so let us not
21672             // allow removing a package if it provides a lib others depend on.
21673             pkg = mPackages.get(packageName);
21674 
21675             allUsers = mUserManager.getUserIds();
21676 
21677             if (pkg != null && pkg.getStaticSharedLibName() != null) {
21678                 SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
21679                         pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
21680                 if (libraryInfo != null) {
21681                     for (int currUserId : allUsers) {
21682                         if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
21683                             continue;
21684                         }
21685                         List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
21686                                 libraryInfo, MATCH_KNOWN_PACKAGES, Process.SYSTEM_UID, currUserId);
21687                         if (!ArrayUtils.isEmpty(libClientPackages)) {
21688                             Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName()
21689                                     + " hosting lib " + libraryInfo.getName() + " version "
21690                                     + libraryInfo.getLongVersion() + " used by " + libClientPackages
21691                                     + " for user " + currUserId);
21692                             return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
21693                         }
21694                     }
21695                 }
21696             }
21697 
21698             info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
21699 
21700             if (isUpdatedSystemApp(uninstalledPs)
21701                     && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
21702                 // We're downgrading a system app, which will apply to all users, so
21703                 // freeze them all during the downgrade
21704                 freezeUser = UserHandle.USER_ALL;
21705                 priorUserStates = new SparseArray<>();
21706                 for (int i = 0; i < allUsers.length; i++) {
21707                     PackageUserState userState = uninstalledPs.readUserState(allUsers[i]);
21708                     priorUserStates.put(allUsers[i],
21709                             new TempUserState(userState.enabled, userState.lastDisableAppCaller,
21710                                     userState.installed));
21711                 }
21712             } else {
21713                 freezeUser = removeUser;
21714                 priorUserStates = null;
21715             }
21716         }
21717 
21718         synchronized (mInstallLock) {
21719             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
21720             try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
21721                     deleteFlags, "deletePackageX")) {
21722                 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
21723                         deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
21724             }
21725             synchronized (mLock) {
21726                 if (res) {
21727                     if (pkg != null) {
21728                         mInstantAppRegistry.onPackageUninstalledLPw(pkg, uninstalledPs,
21729                                 info.removedUsers);
21730                     }
21731                     updateSequenceNumberLP(uninstalledPs, info.removedUsers);
21732                     updateInstantAppInstallerLocked(packageName);
21733                 }
21734             }
21735             ApplicationPackageManager.invalidateGetPackagesForUidCache();
21736         }
21737 
21738         if (res) {
21739             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
21740             info.sendPackageRemovedBroadcasts(killApp, removedBySystem);
21741             info.sendSystemPackageUpdatedBroadcasts();
21742         }
21743         // Force a gc here.
21744         Runtime.getRuntime().gc();
21745         // Delete the resources here after sending the broadcast to let
21746         // other processes clean up before deleting resources.
21747         synchronized (mInstallLock) {
21748             if (info.args != null) {
21749                 info.args.doPostDeleteLI(true);
21750             }
21751 
21752             boolean reEnableStub = false;
21753 
21754             if (priorUserStates != null) {
21755                 synchronized (mLock) {
21756                     for (int i = 0; i < allUsers.length; i++) {
21757                         TempUserState priorUserState = priorUserStates.get(allUsers[i]);
21758                         int enabledState = priorUserState.enabledState;
21759                         PackageSetting pkgSetting = getPackageSetting(packageName);
21760                         pkgSetting.setEnabled(enabledState, allUsers[i],
21761                                 priorUserState.lastDisableAppCaller);
21762 
21763                         AndroidPackage aPkg = pkgSetting.getPkg();
21764                         boolean pkgEnabled = aPkg != null && aPkg.isEnabled();
21765                         if (!reEnableStub && priorUserState.installed
21766                                 && ((enabledState == COMPONENT_ENABLED_STATE_DEFAULT && pkgEnabled)
21767                                         || enabledState == COMPONENT_ENABLED_STATE_ENABLED)) {
21768                             reEnableStub = true;
21769                         }
21770                     }
21771                     mSettings.writeAllUsersPackageRestrictionsLPr();
21772                 }
21773             }
21774 
21775             final AndroidPackage stubPkg =
21776                     (disabledSystemPs == null) ? null : disabledSystemPs.pkg;
21777             if (stubPkg != null && stubPkg.isStub()) {
21778                 final PackageSetting stubPs;
21779                 synchronized (mLock) {
21780                     stubPs = mSettings.getPackageLPr(stubPkg.getPackageName());
21781                 }
21782 
21783                 if (stubPs != null) {
21784                     if (reEnableStub) {
21785                         if (DEBUG_COMPRESSION) {
21786                             Slog.i(TAG, "Enabling system stub after removal; pkg: "
21787                                     + stubPkg.getPackageName());
21788                         }
21789                         enableCompressedPackage(stubPkg, stubPs);
21790                     } else if (DEBUG_COMPRESSION) {
21791                         Slog.i(TAG, "System stub disabled for all users, leaving uncompressed "
21792                                 + "after removal; pkg: " + stubPkg.getPackageName());
21793                     }
21794                 }
21795             }
21796         }
21797 
21798         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
21799     }
21800 
21801     static class PackageRemovedInfo {
21802         final PackageSender packageSender;
21803         String removedPackage;
21804         String installerPackageName;
21805         int uid = -1;
21806         int removedAppId = -1;
21807         int[] origUsers;
21808         int[] removedUsers = null;
21809         int[] broadcastUsers = null;
21810         int[] instantUserIds = null;
21811         SparseArray<Integer> installReasons;
21812         SparseArray<Integer> uninstallReasons;
21813         boolean isRemovedPackageSystemUpdate = false;
21814         boolean isUpdate;
21815         boolean dataRemoved;
21816         boolean removedForAllUsers;
21817         boolean isStaticSharedLib;
21818         // a two dimensional array mapping userId to the set of appIds that can receive notice
21819         // of package changes
21820         SparseArray<int[]> broadcastAllowList;
21821         // Clean up resources deleted packages.
21822         InstallArgs args = null;
21823 
PackageRemovedInfo(PackageSender packageSender)21824         PackageRemovedInfo(PackageSender packageSender) {
21825             this.packageSender = packageSender;
21826         }
21827 
sendPackageRemovedBroadcasts(boolean killApp, boolean removedBySystem)21828         void sendPackageRemovedBroadcasts(boolean killApp, boolean removedBySystem) {
21829             sendPackageRemovedBroadcastInternal(killApp, removedBySystem);
21830         }
21831 
sendSystemPackageUpdatedBroadcasts()21832         void sendSystemPackageUpdatedBroadcasts() {
21833             if (isRemovedPackageSystemUpdate) {
21834                 sendSystemPackageUpdatedBroadcastsInternal();
21835             }
21836         }
21837 
sendSystemPackageUpdatedBroadcastsInternal()21838         private void sendSystemPackageUpdatedBroadcastsInternal() {
21839             Bundle extras = new Bundle(2);
21840             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
21841             extras.putBoolean(Intent.EXTRA_REPLACING, true);
21842             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, extras,
21843                     0, null /*targetPackage*/, null, null, null, broadcastAllowList, null);
21844             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
21845                     extras, 0, null /*targetPackage*/, null, null, null, broadcastAllowList, null);
21846             packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, null, 0,
21847                     removedPackage, null, null, null, null /* broadcastAllowList */,
21848                     getTemporaryAppAllowlistBroadcastOptions(REASON_PACKAGE_REPLACED).toBundle());
21849             if (installerPackageName != null) {
21850                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
21851                         removedPackage, extras, 0 /*flags*/,
21852                         installerPackageName, null, null, null, null /* broadcastAllowList */,
21853                         null);
21854                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
21855                         removedPackage, extras, 0 /*flags*/,
21856                         installerPackageName, null, null, null, null /* broadcastAllowList */,
21857                         null);
21858             }
21859         }
21860 
sendPackageRemovedBroadcastInternal(boolean killApp, boolean removedBySystem)21861         private void sendPackageRemovedBroadcastInternal(boolean killApp, boolean removedBySystem) {
21862             // Don't send static shared library removal broadcasts as these
21863             // libs are visible only the the apps that depend on them an one
21864             // cannot remove the library if it has a dependency.
21865             if (isStaticSharedLib) {
21866                 return;
21867             }
21868             Bundle extras = new Bundle(2);
21869             final int removedUid = removedAppId >= 0  ? removedAppId : uid;
21870             extras.putInt(Intent.EXTRA_UID, removedUid);
21871             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
21872             extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
21873             extras.putBoolean(Intent.EXTRA_USER_INITIATED, !removedBySystem);
21874             if (isUpdate || isRemovedPackageSystemUpdate) {
21875                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
21876             }
21877             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
21878             if (removedPackage != null) {
21879                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
21880                         removedPackage, extras, 0, null /*targetPackage*/, null,
21881                         broadcastUsers, instantUserIds, broadcastAllowList, null);
21882                 if (installerPackageName != null) {
21883                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
21884                             removedPackage, extras, 0 /*flags*/,
21885                             installerPackageName, null, broadcastUsers, instantUserIds, null, null);
21886                 }
21887                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED_INTERNAL,
21888                         removedPackage, extras, 0 /*flags*/, PLATFORM_PACKAGE_NAME,
21889                         null /*finishedReceiver*/, broadcastUsers, instantUserIds,
21890                         broadcastAllowList, null /*bOptions*/);
21891                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
21892                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
21893                             removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null,
21894                             null, broadcastUsers, instantUserIds, broadcastAllowList, null);
21895                     packageSender.notifyPackageRemoved(removedPackage, removedUid);
21896                 }
21897             }
21898             if (removedAppId >= 0) {
21899                 // If a system app's updates are uninstalled the UID is not actually removed. Some
21900                 // services need to know the package name affected.
21901                 if (extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
21902                     extras.putString(Intent.EXTRA_PACKAGE_NAME, removedPackage);
21903                 }
21904 
21905                 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
21906                         null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
21907                         null, null, broadcastUsers, instantUserIds, broadcastAllowList, null);
21908             }
21909         }
21910 
populateUsers(int[] userIds, PackageSetting deletedPackageSetting)21911         void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
21912             removedUsers = userIds;
21913             if (removedUsers == null) {
21914                 broadcastUsers = null;
21915                 return;
21916             }
21917 
21918             broadcastUsers = EMPTY_INT_ARRAY;
21919             instantUserIds = EMPTY_INT_ARRAY;
21920             for (int i = userIds.length - 1; i >= 0; --i) {
21921                 final int userId = userIds[i];
21922                 if (deletedPackageSetting.getInstantApp(userId)) {
21923                     instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
21924                 } else {
21925                     broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
21926                 }
21927             }
21928         }
21929     }
21930 
21931     /*
21932      * This method deletes the package from internal data structures. If the DELETE_KEEP_DATA
21933      * flag is not set, the data directory is removed as well.
21934      * make sure this flag is set for partially installed apps. If not its meaningless to
21935      * delete a partially installed application.
21936      */
removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles, PackageRemovedInfo outInfo, int flags, boolean writeSettings)21937     private void removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles,
21938             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
21939         String packageName = deletedPs.name;
21940         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
21941         // Retrieve object to delete permissions for shared user later on
21942         final AndroidPackage deletedPkg = deletedPs.pkg;
21943         if (outInfo != null) {
21944             outInfo.removedPackage = packageName;
21945             outInfo.installerPackageName = deletedPs.installSource.installerPackageName;
21946             outInfo.isStaticSharedLib = deletedPkg != null
21947                     && deletedPkg.getStaticSharedLibName() != null;
21948             outInfo.populateUsers(deletedPs == null ? null
21949                     : deletedPs.queryInstalledUsers(mUserManager.getUserIds(), true), deletedPs);
21950         }
21951 
21952         removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0);
21953 
21954         if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
21955             final AndroidPackage resolvedPkg;
21956             if (deletedPkg != null) {
21957                 resolvedPkg = deletedPkg;
21958             } else {
21959                 // We don't have a parsed package when it lives on an ejected
21960                 // adopted storage device, so fake something together
21961                 resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.name,
21962                         deletedPs.volumeUuid);
21963             }
21964             destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
21965                     FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
21966             destroyAppProfilesLIF(resolvedPkg);
21967             if (outInfo != null) {
21968                 outInfo.dataRemoved = true;
21969             }
21970         }
21971 
21972         int removedAppId = -1;
21973 
21974         // writer
21975         boolean installedStateChanged = false;
21976         if (deletedPs != null) {
21977             if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
21978                 final SparseBooleanArray changedUsers = new SparseBooleanArray();
21979                 synchronized (mLock) {
21980                     mDomainVerificationManager.clearPackage(deletedPs.name);
21981                     mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName);
21982                     mAppsFilter.removePackage(getPackageSetting(packageName));
21983                     removedAppId = mSettings.removePackageLPw(packageName);
21984                     if (outInfo != null) {
21985                         outInfo.removedAppId = removedAppId;
21986                     }
21987                     if (!mSettings.isDisabledSystemPackageLPr(packageName)) {
21988                         // If we don't have a disabled system package to reinstall, the package is
21989                         // really gone and its permission state should be removed.
21990                         final SharedUserSetting sus = deletedPs.getSharedUser();
21991                         List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages()
21992                                 : null;
21993                         if (sharedUserPkgs == null) {
21994                             sharedUserPkgs = Collections.emptyList();
21995                         }
21996                         mPermissionManager.onPackageUninstalled(packageName, deletedPs.appId,
21997                                 deletedPs.pkg, sharedUserPkgs, UserHandle.USER_ALL);
21998                     }
21999                     clearPackagePreferredActivitiesLPw(
22000                             deletedPs.name, changedUsers, UserHandle.USER_ALL);
22001                 }
22002                 if (changedUsers.size() > 0) {
22003                     updateDefaultHomeNotLocked(changedUsers);
22004                     postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
22005                 }
22006             }
22007             // make sure to preserve per-user disabled state if this removal was just
22008             // a downgrade of a system app to the factory package
22009             if (outInfo != null && outInfo.origUsers != null) {
22010                 if (DEBUG_REMOVE) {
22011                     Slog.d(TAG, "Propagating install state across downgrade");
22012                 }
22013                 for (int userId : allUserHandles) {
22014                     final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
22015                     if (DEBUG_REMOVE) {
22016                         Slog.d(TAG, "    user " + userId + " => " + installed);
22017                     }
22018                     if (installed != deletedPs.getInstalled(userId)) {
22019                         installedStateChanged = true;
22020                     }
22021                     deletedPs.setInstalled(installed, userId);
22022                     if (installed) {
22023                         deletedPs.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId);
22024                     }
22025                 }
22026             }
22027         }
22028         synchronized (mLock) {
22029             // can downgrade to reader
22030             if (writeSettings) {
22031                 // Save settings now
22032                 writeSettingsLPrTEMP();
22033             }
22034             if (installedStateChanged) {
22035                 mSettings.writeKernelMappingLPr(deletedPs);
22036             }
22037         }
22038         if (removedAppId != -1) {
22039             // A user ID was deleted here. Go through all users and remove it
22040             // from KeyStore.
22041             removeKeystoreDataIfNeeded(
22042                     mInjector.getUserManagerInternal(), UserHandle.USER_ALL, removedAppId);
22043         }
22044     }
22045 
resolveApexToScanPartition( ApexManager.ActiveApexInfo apexInfo)22046     private static @Nullable ScanPartition resolveApexToScanPartition(
22047             ApexManager.ActiveApexInfo apexInfo) {
22048         for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
22049             ScanPartition sp = SYSTEM_PARTITIONS.get(i);
22050             if (apexInfo.preInstalledApexPath.getAbsolutePath().startsWith(
22051                     sp.getFolder().getAbsolutePath())) {
22052                 return new ScanPartition(apexInfo.apexDirectory, sp, SCAN_AS_APK_IN_APEX);
22053             }
22054         }
22055         return null;
22056     }
22057 
22058     /*
22059      * Tries to delete system package.
22060      */
deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs, @NonNull int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo, boolean writeSettings)22061     private void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
22062             @NonNull int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
22063             boolean writeSettings)
22064             throws SystemDeleteException {
22065         final boolean applyUserRestrictions = outInfo != null && (outInfo.origUsers != null);
22066         final AndroidPackage deletedPkg = deletedPs.pkg;
22067         // Confirm if the system package has been updated
22068         // An updated system app can be deleted. This will also have to restore
22069         // the system pkg from system partition
22070         // reader
22071         final PackageSetting disabledPs = action.disabledPs;
22072         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName()
22073                 + " disabledPs=" + disabledPs);
22074         Slog.d(TAG, "Deleting system pkg from data partition");
22075 
22076         if (DEBUG_REMOVE) {
22077             if (applyUserRestrictions) {
22078                 Slog.d(TAG, "Remembering install states:");
22079                 for (int userId : allUserHandles) {
22080                     final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
22081                     Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
22082                 }
22083             }
22084         }
22085 
22086         if (outInfo != null) {
22087             // Delete the updated package
22088             outInfo.isRemovedPackageSystemUpdate = true;
22089         }
22090 
22091         if (disabledPs.versionCode < deletedPs.versionCode) {
22092             // Delete data for downgrades
22093             flags &= ~PackageManager.DELETE_KEEP_DATA;
22094         } else {
22095             // Preserve data by setting flag
22096             flags |= PackageManager.DELETE_KEEP_DATA;
22097         }
22098 
22099         deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
22100                 outInfo, writeSettings);
22101 
22102         // writer
22103         synchronized (mLock) {
22104             // NOTE: The system package always needs to be enabled; even if it's for
22105             // a compressed stub. If we don't, installing the system package fails
22106             // during scan [scanning checks the disabled packages]. We will reverse
22107             // this later, after we've "installed" the stub.
22108             // Reinstate the old system package
22109             enableSystemPackageLPw(disabledPs.pkg);
22110             // Remove any native libraries from the upgraded package.
22111             removeNativeBinariesLI(deletedPs);
22112         }
22113 
22114         // Install the system package
22115         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
22116         try {
22117             installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
22118                     outInfo == null ? null : outInfo.origUsers, writeSettings);
22119         } catch (PackageManagerException e) {
22120             Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": "
22121                     + e.getMessage());
22122             // TODO(patb): can we avoid this; throw would come from scan...
22123             throw new SystemDeleteException(e);
22124         } finally {
22125             if (disabledPs.pkg.isStub()) {
22126                 // We've re-installed the stub; make sure it's disabled here. If package was
22127                 // originally enabled, we'll install the compressed version of the application
22128                 // and re-enable it afterward.
22129                 final PackageSetting stubPs = mSettings.getPackageLPr(deletedPkg.getPackageName());
22130                 if (stubPs != null) {
22131                     int userId = action.user == null
22132                             ? UserHandle.USER_ALL : action.user.getIdentifier();
22133                     if (userId == UserHandle.USER_ALL) {
22134                         for (int aUserId : allUserHandles) {
22135                             stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, aUserId, "android");
22136                         }
22137                     } else if (userId >= UserHandle.USER_SYSTEM) {
22138                         stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, userId, "android");
22139                     }
22140                 }
22141             }
22142         }
22143     }
22144 
22145     /**
22146      * Installs a package that's already on the system partition.
22147      */
installPackageFromSystemLIF(@onNull String codePathString, @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)22148     private AndroidPackage installPackageFromSystemLIF(@NonNull String codePathString,
22149             @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)
22150             throws PackageManagerException {
22151         final File codePath = new File(codePathString);
22152         @ParseFlags int parseFlags =
22153                 mDefParseFlags
22154                 | ParsingPackageUtils.PARSE_MUST_BE_APK
22155                 | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
22156         @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
22157         for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
22158             ScanPartition partition = mDirsToScanAsSystem.get(i);
22159             if (partition.containsFile(codePath)) {
22160                 scanFlags |= partition.scanFlag;
22161                 if (partition.containsPrivApp(codePath)) {
22162                     scanFlags |= SCAN_AS_PRIVILEGED;
22163                 }
22164                 break;
22165             }
22166         }
22167 
22168         final AndroidPackage pkg =
22169                 scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
22170 
22171         PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
22172 
22173         try {
22174             // update shared libraries for the newly re-installed system package
22175             updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
22176                     Collections.unmodifiableMap(mPackages));
22177         } catch (PackageManagerException e) {
22178             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
22179         }
22180 
22181         prepareAppDataAfterInstallLIF(pkg);
22182 
22183         // writer
22184         synchronized (mLock) {
22185             PackageSetting ps = mSettings.getPackageLPr(pkg.getPackageName());
22186 
22187             final boolean applyUserRestrictions = origUserHandles != null;
22188             if (applyUserRestrictions) {
22189                 boolean installedStateChanged = false;
22190                 if (DEBUG_REMOVE) {
22191                     Slog.d(TAG, "Propagating install state across reinstall");
22192                 }
22193                 for (int userId : allUserHandles) {
22194                     final boolean installed = ArrayUtils.contains(origUserHandles, userId);
22195                     if (DEBUG_REMOVE) {
22196                         Slog.d(TAG, "    user " + userId + " => " + installed);
22197                     }
22198                     if (installed != ps.getInstalled(userId)) {
22199                         installedStateChanged = true;
22200                     }
22201                     ps.setInstalled(installed, userId);
22202                     if (installed) {
22203                         ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId);
22204                     }
22205                 }
22206                 // Regardless of writeSettings we need to ensure that this restriction
22207                 // state propagation is persisted
22208                 mSettings.writeAllUsersPackageRestrictionsLPr();
22209                 if (installedStateChanged) {
22210                     mSettings.writeKernelMappingLPr(ps);
22211                 }
22212             }
22213 
22214             // The method below will take care of removing obsolete permissions and granting
22215             // install permissions.
22216             mPermissionManager.onPackageInstalled(pkg,
22217                     PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
22218                     UserHandle.USER_ALL);
22219             for (final int userId : allUserHandles) {
22220                 if (applyUserRestrictions) {
22221                     mSettings.writePermissionStateForUserLPr(userId, false);
22222                 }
22223             }
22224 
22225             // can downgrade to reader here
22226             if (writeSettings) {
22227                 writeSettingsLPrTEMP();
22228             }
22229         }
22230         return pkg;
22231     }
22232 
deleteInstalledPackageLIF(PackageSetting ps, boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles, PackageRemovedInfo outInfo, boolean writeSettings)22233     private void deleteInstalledPackageLIF(PackageSetting ps,
22234             boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles,
22235             PackageRemovedInfo outInfo, boolean writeSettings) {
22236         synchronized (mLock) {
22237             if (outInfo != null) {
22238                 outInfo.uid = ps.appId;
22239                 outInfo.broadcastAllowList = mAppsFilter.getVisibilityAllowList(ps,
22240                         allUserHandles, mSettings.getPackagesLocked());
22241             }
22242         }
22243 
22244         // Delete package data from internal structures and also remove data if flag is set
22245         removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
22246 
22247         // Delete application code and resources only for parent packages
22248         if (deleteCodeAndResources && (outInfo != null)) {
22249             outInfo.args = createInstallArgsForExisting(
22250                     ps.getPathString(), getAppDexInstructionSets(
22251                             ps.primaryCpuAbiString, ps.secondaryCpuAbiString));
22252             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
22253         }
22254     }
22255 
22256     @Override
setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId)22257     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
22258             int userId) {
22259         mContext.enforceCallingOrSelfPermission(
22260                 android.Manifest.permission.DELETE_PACKAGES, null);
22261         // TODO (b/157774108): This should fail on non-existent packages.
22262         synchronized (mLock) {
22263             // Cannot block uninstall of static shared libs as they are
22264             // considered a part of the using app (emulating static linking).
22265             // Also static libs are installed always on internal storage.
22266             AndroidPackage pkg = mPackages.get(packageName);
22267             if (pkg != null && pkg.getStaticSharedLibName() != null) {
22268                 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
22269                         + " providing static shared library: " + pkg.getStaticSharedLibName());
22270                 return false;
22271             }
22272             mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
22273             mSettings.writePackageRestrictionsLPr(userId);
22274         }
22275         return true;
22276     }
22277 
22278     @Override
getBlockUninstallForUser(String packageName, int userId)22279     public boolean getBlockUninstallForUser(String packageName, int userId) {
22280         synchronized (mLock) {
22281             final PackageSetting ps = mSettings.getPackageLPr(packageName);
22282             if (ps == null || shouldFilterApplicationLocked(ps, Binder.getCallingUid(), userId)) {
22283                 return false;
22284             }
22285             return mSettings.getBlockUninstallLPr(userId, packageName);
22286         }
22287     }
22288 
22289     @Override
setRequiredForSystemUser(String packageName, boolean systemUserApp)22290     public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
22291         enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
22292         synchronized (mLock) {
22293             PackageSetting ps = mSettings.getPackageLPr(packageName);
22294             if (ps == null) {
22295                 Log.w(TAG, "Package doesn't exist: " + packageName);
22296                 return false;
22297             }
22298             if (systemUserApp) {
22299                 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
22300             } else {
22301                 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
22302             }
22303             writeSettingsLPrTEMP();
22304         }
22305         return true;
22306     }
22307 
22308     private static class DeletePackageAction {
22309         public final PackageSetting deletingPs;
22310         public final PackageSetting disabledPs;
22311         public final PackageRemovedInfo outInfo;
22312         public final int flags;
22313         public final UserHandle user;
22314 
DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs, PackageRemovedInfo outInfo, int flags, UserHandle user)22315         private DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs,
22316                 PackageRemovedInfo outInfo, int flags, UserHandle user) {
22317             this.deletingPs = deletingPs;
22318             this.disabledPs = disabledPs;
22319             this.outInfo = outInfo;
22320             this.flags = flags;
22321             this.user = user;
22322         }
22323     }
22324 
22325     /**
22326      * @return a {@link DeletePackageAction} if the provided package and related state may be
22327      * deleted, {@code null} otherwise.
22328      */
22329     @Nullable
22330     @GuardedBy("mLock")
mayDeletePackageLocked( PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs, int flags, UserHandle user)22331     private static DeletePackageAction mayDeletePackageLocked(
22332             PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
22333             int flags, UserHandle user) {
22334         if (ps == null) {
22335             return null;
22336         }
22337         if (isSystemApp(ps)) {
22338             final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0;
22339             final boolean deleteAllUsers =
22340                     user == null || user.getIdentifier() == UserHandle.USER_ALL;
22341             if ((!deleteSystem || deleteAllUsers) && disabledPs == null) {
22342                 Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.getPackageName());
22343                 return null;
22344             }
22345             // Confirmed if the system package has been updated
22346             // An updated system app can be deleted. This will also have to restore
22347             // the system pkg from system partition reader
22348         }
22349         return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
22350     }
22351 
22352     /*
22353      * This method handles package deletion in general
22354      */
deletePackageLIF(@onNull String packageName, UserHandle user, boolean deleteCodeAndResources, @NonNull int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings, ParsedPackage replacingPackage)22355     private boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
22356             boolean deleteCodeAndResources, @NonNull int[] allUserHandles, int flags,
22357             PackageRemovedInfo outInfo, boolean writeSettings,
22358             ParsedPackage replacingPackage) {
22359         final DeletePackageAction action;
22360         synchronized (mLock) {
22361             final PackageSetting ps = mSettings.getPackageLPr(packageName);
22362             final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
22363             action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user);
22364         }
22365         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
22366         if (null == action) {
22367             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: action was null");
22368             return false;
22369         }
22370 
22371 
22372         try {
22373             executeDeletePackageLIF(action, packageName, deleteCodeAndResources,
22374                     allUserHandles, writeSettings, replacingPackage);
22375         } catch (SystemDeleteException e) {
22376             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: system deletion failure", e);
22377             return false;
22378         }
22379         return true;
22380     }
22381 
22382     private static class SystemDeleteException extends Exception {
22383         public final PackageManagerException reason;
22384 
SystemDeleteException(PackageManagerException reason)22385         private SystemDeleteException(PackageManagerException reason) {
22386             this.reason = reason;
22387         }
22388     }
22389 
22390     /** Deletes a package. Only throws when install of a disabled package fails. */
executeDeletePackageLIF(DeletePackageAction action, String packageName, boolean deleteCodeAndResources, @NonNull int[] allUserHandles, boolean writeSettings, ParsedPackage replacingPackage)22391     private void executeDeletePackageLIF(DeletePackageAction action,
22392             String packageName, boolean deleteCodeAndResources,
22393             @NonNull int[] allUserHandles, boolean writeSettings,
22394             ParsedPackage replacingPackage) throws SystemDeleteException {
22395         final PackageSetting ps = action.deletingPs;
22396         final PackageRemovedInfo outInfo = action.outInfo;
22397         final UserHandle user = action.user;
22398         final int flags = action.flags;
22399         final boolean systemApp = isSystemApp(ps);
22400 
22401         // We need to get the permission state before package state is (potentially) destroyed.
22402         final SparseBooleanArray hadSuspendAppsPermission = new SparseBooleanArray();
22403         for (int userId : allUserHandles) {
22404             hadSuspendAppsPermission.put(userId, checkPermission(Manifest.permission.SUSPEND_APPS,
22405                     packageName, userId) == PERMISSION_GRANTED);
22406         }
22407 
22408         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
22409 
22410         if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
22411                 && userId != UserHandle.USER_ALL) {
22412             // The caller is asking that the package only be deleted for a single
22413             // user.  To do this, we just mark its uninstalled state and delete
22414             // its data. If this is a system app, we only allow this to happen if
22415             // they have set the special DELETE_SYSTEM_APP which requests different
22416             // semantics than normal for uninstalling system apps.
22417             final boolean clearPackageStateAndReturn;
22418             synchronized (mLock) {
22419                 markPackageUninstalledForUserLPw(ps, user);
22420                 if (!systemApp) {
22421                     // Do not uninstall the APK if an app should be cached
22422                     boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
22423                     if (ps.isAnyInstalled(mUserManager.getUserIds()) || keepUninstalledPackage) {
22424                         // Other users still have this package installed, so all
22425                         // we need to do is clear this user's data and save that
22426                         // it is uninstalled.
22427                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
22428                         clearPackageStateAndReturn = true;
22429                     } else {
22430                         // We need to set it back to 'installed' so the uninstall
22431                         // broadcasts will be sent correctly.
22432                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
22433                         ps.setInstalled(true, userId);
22434                         mSettings.writeKernelMappingLPr(ps);
22435                         clearPackageStateAndReturn = false;
22436                     }
22437                 } else {
22438                     // This is a system app, so we assume that the
22439                     // other users still have this package installed, so all
22440                     // we need to do is clear this user's data and save that
22441                     // it is uninstalled.
22442                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
22443                     clearPackageStateAndReturn = true;
22444                 }
22445             }
22446             if (clearPackageStateAndReturn) {
22447                 clearPackageStateForUserLIF(ps, userId, outInfo, flags);
22448                 synchronized (mLock) {
22449                     scheduleWritePackageRestrictionsLocked(user);
22450                 }
22451                 return;
22452             }
22453         }
22454 
22455         // TODO(b/109941548): break reasons for ret = false out into mayDelete method
22456         if (systemApp) {
22457             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
22458             // When an updated system application is deleted we delete the existing resources
22459             // as well and fall back to existing code in system partition
22460             deleteSystemPackageLIF(action, ps, allUserHandles, flags, outInfo, writeSettings);
22461         } else {
22462             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
22463             deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
22464                     outInfo, writeSettings);
22465         }
22466 
22467         // If the package removed had SUSPEND_APPS, unset any restrictions that might have been in
22468         // place for all affected users.
22469         int[] affectedUserIds = (outInfo != null) ? outInfo.removedUsers : null;
22470         if (affectedUserIds == null) {
22471             affectedUserIds = resolveUserIds(userId);
22472         }
22473         for (final int affectedUserId : affectedUserIds) {
22474             if (hadSuspendAppsPermission.get(affectedUserId)) {
22475                 unsuspendForSuspendingPackage(packageName, affectedUserId);
22476                 removeAllDistractingPackageRestrictions(affectedUserId);
22477             }
22478         }
22479 
22480         // Take a note whether we deleted the package for all users
22481         if (outInfo != null) {
22482             outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
22483         }
22484     }
22485 
22486     @GuardedBy("mLock")
markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user)22487     private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
22488         final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
22489                 ? mUserManager.getUserIds() : new int[] {user.getIdentifier()};
22490         for (int nextUserId : userIds) {
22491             if (DEBUG_REMOVE) {
22492                 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
22493             }
22494             ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
22495                     false /*installed*/,
22496                     true /*stopped*/,
22497                     true /*notLaunched*/,
22498                     false /*hidden*/,
22499                     0 /*distractionFlags*/,
22500                     false /*suspended*/,
22501                     null /*suspendParams*/,
22502                     false /*instantApp*/,
22503                     false /*virtualPreload*/,
22504                     null /*lastDisableAppCaller*/,
22505                     null /*enabledComponents*/,
22506                     null /*disabledComponents*/,
22507                     PackageManager.INSTALL_REASON_UNKNOWN,
22508                     PackageManager.UNINSTALL_REASON_UNKNOWN,
22509                     null /*harmfulAppWarning*/,
22510                     null /*splashScreenTheme*/);
22511         }
22512         mSettings.writeKernelMappingLPr(ps);
22513     }
22514 
clearPackageStateForUserLIF(PackageSetting ps, int userId, PackageRemovedInfo outInfo, int flags)22515     private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
22516             PackageRemovedInfo outInfo, int flags) {
22517         final AndroidPackage pkg;
22518         synchronized (mLock) {
22519             pkg = mPackages.get(ps.name);
22520         }
22521 
22522         destroyAppProfilesLIF(pkg);
22523 
22524         final SharedUserSetting sus = ps.getSharedUser();
22525         List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : null;
22526         if (sharedUserPkgs == null) {
22527             sharedUserPkgs = Collections.emptyList();
22528         }
22529         final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds()
22530                 : new int[] {userId};
22531         for (int nextUserId : userIds) {
22532             if (DEBUG_REMOVE) {
22533                 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
22534                         + nextUserId);
22535             }
22536             if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
22537                 destroyAppDataLIF(pkg, nextUserId,
22538                         FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
22539             }
22540             removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId);
22541             clearPackagePreferredActivities(ps.name, nextUserId);
22542             mDomainVerificationManager.clearPackageForUser(ps.name, nextUserId);
22543         }
22544         mPermissionManager.onPackageUninstalled(ps.name, ps.appId, pkg, sharedUserPkgs, userId);
22545 
22546         if (outInfo != null) {
22547             if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
22548                 outInfo.dataRemoved = true;
22549             }
22550             outInfo.removedPackage = ps.name;
22551             outInfo.installerPackageName = ps.installSource.installerPackageName;
22552             outInfo.isStaticSharedLib = pkg != null && pkg.getStaticSharedLibName() != null;
22553             outInfo.removedAppId = ps.appId;
22554             outInfo.removedUsers = userIds;
22555             outInfo.broadcastUsers = userIds;
22556         }
22557     }
22558 
22559     @Override
clearApplicationProfileData(String packageName)22560     public void clearApplicationProfileData(String packageName) {
22561         enforceSystemOrRoot("Only the system can clear all profile data");
22562 
22563         final AndroidPackage pkg;
22564         synchronized (mLock) {
22565             pkg = mPackages.get(packageName);
22566         }
22567 
22568         try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
22569             synchronized (mInstallLock) {
22570                 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
22571             }
22572         }
22573     }
22574 
22575     @Override
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)22576     public void clearApplicationUserData(final String packageName,
22577             final IPackageDataObserver observer, final int userId) {
22578         mContext.enforceCallingOrSelfPermission(
22579                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
22580 
22581         final int callingUid = Binder.getCallingUid();
22582         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
22583                 false /* checkShell */, "clear application data");
22584 
22585         final boolean filterApp;
22586         synchronized (mLock) {
22587             final PackageSetting ps = mSettings.getPackageLPr(packageName);
22588             filterApp = shouldFilterApplicationLocked(ps, callingUid, userId);
22589         }
22590         if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
22591             throw new SecurityException("Cannot clear data for a protected package: "
22592                     + packageName);
22593         }
22594         // Queue up an async operation since the package deletion may take a little while.
22595         mHandler.post(new Runnable() {
22596             public void run() {
22597                 mHandler.removeCallbacks(this);
22598                 final boolean succeeded;
22599                 if (!filterApp) {
22600                     try (PackageFreezer freezer = freezePackage(packageName,
22601                             "clearApplicationUserData")) {
22602                         synchronized (mInstallLock) {
22603                             succeeded = clearApplicationUserDataLIF(packageName, userId);
22604                         }
22605                         synchronized (mLock) {
22606                             mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
22607                                     packageName, userId);
22608                         }
22609                     }
22610                     if (succeeded) {
22611                         // invoke DeviceStorageMonitor's update method to clear any notifications
22612                         DeviceStorageMonitorInternal dsm = LocalServices
22613                                 .getService(DeviceStorageMonitorInternal.class);
22614                         if (dsm != null) {
22615                             dsm.checkMemory();
22616                         }
22617                         if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
22618                                 == PERMISSION_GRANTED) {
22619                             unsuspendForSuspendingPackage(packageName, userId);
22620                             removeAllDistractingPackageRestrictions(userId);
22621                             flushPackageRestrictionsAsUserInternalLocked(userId);
22622                         }
22623                     }
22624                 } else {
22625                     succeeded = false;
22626                 }
22627                 if (observer != null) {
22628                     try {
22629                         observer.onRemoveCompleted(packageName, succeeded);
22630                     } catch (RemoteException e) {
22631                         Log.i(TAG, "Observer no longer exists.");
22632                     }
22633                 } //end if observer
22634             } //end run
22635         });
22636     }
22637 
clearApplicationUserDataLIF(String packageName, int userId)22638     private boolean clearApplicationUserDataLIF(String packageName, int userId) {
22639         if (packageName == null) {
22640             Slog.w(TAG, "Attempt to delete null packageName.");
22641             return false;
22642         }
22643 
22644         // Try finding details about the requested package
22645         AndroidPackage pkg;
22646         PackageSetting ps;
22647         synchronized (mLock) {
22648             pkg = mPackages.get(packageName);
22649             ps = mSettings.getPackageLPr(packageName);
22650             if (pkg == null) {
22651                 if (ps != null) {
22652                     pkg = ps.pkg;
22653                 }
22654             }
22655         }
22656         if (pkg == null) {
22657             Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
22658             return false;
22659         }
22660         mPermissionManager.resetRuntimePermissions(pkg, userId);
22661 
22662         clearAppDataLIF(pkg, userId,
22663                 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
22664 
22665         final int appId = UserHandle.getAppId(pkg.getUid());
22666         removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId);
22667 
22668         UserManagerInternal umInternal = mInjector.getUserManagerInternal();
22669         StorageManagerInternal smInternal = mInjector.getLocalService(StorageManagerInternal.class);
22670         final int flags;
22671         if (StorageManager.isUserKeyUnlocked(userId) && smInternal.isCeStoragePrepared(userId)) {
22672             flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22673         } else if (umInternal.isUserRunning(userId)) {
22674             flags = StorageManager.FLAG_STORAGE_DE;
22675         } else {
22676             flags = 0;
22677         }
22678         prepareAppDataContentsLIF(pkg, ps, userId, flags);
22679 
22680         return true;
22681     }
22682 
resetNetworkPolicies(int userId)22683     private void resetNetworkPolicies(int userId) {
22684         mInjector.getLocalService(NetworkPolicyManagerInternal.class).resetUserState(userId);
22685     }
22686 
22687     /**
22688      * Remove entries from the keystore daemon. Will only remove it if the
22689      * {@code appId} is valid.
22690      */
removeKeystoreDataIfNeeded(UserManagerInternal um, @UserIdInt int userId, @AppIdInt int appId)22691     private static void removeKeystoreDataIfNeeded(UserManagerInternal um, @UserIdInt int userId,
22692             @AppIdInt int appId) {
22693         if (appId < 0) {
22694             return;
22695         }
22696 
22697         final KeyStore keyStore = KeyStore.getInstance();
22698         if (keyStore != null) {
22699             if (userId == UserHandle.USER_ALL) {
22700                 for (final int individual : um.getUserIds()) {
22701                     keyStore.clearUid(UserHandle.getUid(individual, appId));
22702                 }
22703             } else {
22704                 keyStore.clearUid(UserHandle.getUid(userId, appId));
22705             }
22706         } else {
22707             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
22708         }
22709     }
22710 
22711     @Override
deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)22712     public void deleteApplicationCacheFiles(final String packageName,
22713             final IPackageDataObserver observer) {
22714         final int userId = UserHandle.getCallingUserId();
22715         deleteApplicationCacheFilesAsUser(packageName, userId, observer);
22716     }
22717 
22718     @Override
deleteApplicationCacheFilesAsUser(final String packageName, final int userId, final IPackageDataObserver observer)22719     public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
22720             final IPackageDataObserver observer) {
22721         final int callingUid = Binder.getCallingUid();
22722         if (mContext.checkCallingOrSelfPermission(
22723                 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
22724                 != PackageManager.PERMISSION_GRANTED) {
22725             // If the caller has the old delete cache permission, silently ignore.  Else throw.
22726             if (mContext.checkCallingOrSelfPermission(
22727                     android.Manifest.permission.DELETE_CACHE_FILES)
22728                     == PackageManager.PERMISSION_GRANTED) {
22729                 Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
22730                         android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
22731                         ", silently ignoring");
22732                 return;
22733             }
22734             mContext.enforceCallingOrSelfPermission(
22735                     android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
22736         }
22737         enforceCrossUserPermission(callingUid, userId, /* requireFullPermission= */ true,
22738                 /* checkShell= */ false, "delete application cache files");
22739         final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
22740                 android.Manifest.permission.ACCESS_INSTANT_APPS);
22741 
22742         final AndroidPackage pkg;
22743         synchronized (mLock) {
22744             pkg = mPackages.get(packageName);
22745         }
22746 
22747         // Queue up an async operation since the package deletion may take a little while.
22748         mHandler.post(() -> {
22749             final PackageSetting ps = pkg == null ? null : getPackageSetting(pkg.getPackageName());
22750             boolean doClearData = true;
22751             if (ps != null) {
22752                 final boolean targetIsInstantApp =
22753                         ps.getInstantApp(UserHandle.getUserId(callingUid));
22754                 doClearData = !targetIsInstantApp
22755                         || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
22756             }
22757             if (doClearData) {
22758                 synchronized (mInstallLock) {
22759                     final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
22760                     // We're only clearing cache files, so we don't care if the
22761                     // app is unfrozen and still able to run
22762                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
22763                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22764                 }
22765             }
22766             if (observer != null) {
22767                 try {
22768                     observer.onRemoveCompleted(packageName, true);
22769                 } catch (RemoteException e) {
22770                     Log.i(TAG, "Observer no longer exists.");
22771                 }
22772             }
22773         });
22774     }
22775 
22776     @Override
getPackageSizeInfo(final String packageName, int userId, final IPackageStatsObserver observer)22777     public void getPackageSizeInfo(final String packageName, int userId,
22778             final IPackageStatsObserver observer) {
22779         throw new UnsupportedOperationException(
22780                 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
22781     }
22782 
22783     @GuardedBy("mInstallLock")
getPackageSizeInfoLI(String packageName, int userId, PackageStats stats)22784     private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
22785         final PackageSetting ps;
22786         synchronized (mLock) {
22787             ps = mSettings.getPackageLPr(packageName);
22788             if (ps == null) {
22789                 Slog.w(TAG, "Failed to find settings for " + packageName);
22790                 return false;
22791             }
22792         }
22793 
22794         final String[] packageNames = { packageName };
22795         final long[] ceDataInodes = { ps.getCeDataInode(userId) };
22796         final String[] codePaths = { ps.getPathString() };
22797 
22798         try {
22799             mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
22800                     ps.appId, ceDataInodes, codePaths, stats);
22801 
22802             // For now, ignore code size of packages on system partition
22803             if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
22804                 stats.codeSize = 0;
22805             }
22806 
22807             // External clients expect these to be tracked separately
22808             stats.dataSize -= stats.cacheSize;
22809 
22810         } catch (InstallerException e) {
22811             Slog.w(TAG, String.valueOf(e));
22812             return false;
22813         }
22814 
22815         return true;
22816     }
22817 
22818     @GuardedBy("mLock")
getUidTargetSdkVersionLockedLPr(int uid)22819     private int getUidTargetSdkVersionLockedLPr(int uid) {
22820         final int appId = UserHandle.getAppId(uid);
22821         final Object obj = mSettings.getSettingLPr(appId);
22822         if (obj instanceof SharedUserSetting) {
22823             final SharedUserSetting sus = (SharedUserSetting) obj;
22824             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
22825             final int numPackages = sus.packages.size();
22826             for (int index = 0; index < numPackages; index++) {
22827                 final PackageSetting ps = sus.packages.valueAt(index);
22828                 if (ps.pkg != null) {
22829                     int v = ps.pkg.getTargetSdkVersion();
22830                     if (v < vers) vers = v;
22831                 }
22832             }
22833             return vers;
22834         } else if (obj instanceof PackageSetting) {
22835             final PackageSetting ps = (PackageSetting) obj;
22836             if (ps.pkg != null) {
22837                 return ps.pkg.getTargetSdkVersion();
22838             }
22839         }
22840         return Build.VERSION_CODES.CUR_DEVELOPMENT;
22841     }
22842 
22843     @GuardedBy("mLock")
getPackageTargetSdkVersionLockedLPr(String packageName)22844     private int getPackageTargetSdkVersionLockedLPr(String packageName) {
22845         final AndroidPackage p = mPackages.get(packageName);
22846         if (p != null) {
22847             return p.getTargetSdkVersion();
22848         }
22849         return Build.VERSION_CODES.CUR_DEVELOPMENT;
22850     }
22851 
22852     @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId, boolean removeExisting)22853     public void addPreferredActivity(IntentFilter filter, int match,
22854             ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) {
22855         addPreferredActivity(new WatchedIntentFilter(filter), match, set, activity, true, userId,
22856                 "Adding preferred", removeExisting);
22857     }
22858 
22859     /**
22860      * Variant that takes a {@link WatchedIntentFilter}
22861      */
addPreferredActivity(WatchedIntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId, String opname, boolean removeExisting)22862     public void addPreferredActivity(WatchedIntentFilter filter, int match,
22863             ComponentName[] set, ComponentName activity, boolean always, int userId,
22864             String opname, boolean removeExisting) {
22865         // writer
22866         int callingUid = Binder.getCallingUid();
22867         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
22868                 false /* checkShell */, "add preferred activity");
22869         if (mContext.checkCallingOrSelfPermission(
22870                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
22871                 != PackageManager.PERMISSION_GRANTED) {
22872             synchronized (mLock) {
22873                 if (getUidTargetSdkVersionLockedLPr(callingUid)
22874                         < Build.VERSION_CODES.FROYO) {
22875                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
22876                             + callingUid);
22877                     return;
22878                 }
22879             }
22880             mContext.enforceCallingOrSelfPermission(
22881                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
22882         }
22883         if (filter.countActions() == 0) {
22884             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
22885             return;
22886         }
22887         if (DEBUG_PREFERRED) {
22888             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
22889                     + userId + ":");
22890             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
22891         }
22892         synchronized (mLock) {
22893             final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
22894             final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
22895             if (removeExisting && existing != null) {
22896                 Settings.removeFilters(pir, filter, existing);
22897             }
22898             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
22899             scheduleWritePackageRestrictionsLocked(userId);
22900         }
22901         if (!(isHomeFilter(filter) && updateDefaultHomeNotLocked(userId))) {
22902             postPreferredActivityChangedBroadcast(userId);
22903         }
22904     }
22905 
postPreferredActivityChangedBroadcast(int userId)22906     private void postPreferredActivityChangedBroadcast(int userId) {
22907         mHandler.post(() -> {
22908             final IActivityManager am = ActivityManager.getService();
22909             if (am == null) {
22910                 return;
22911             }
22912 
22913             final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
22914             intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
22915             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
22916             try {
22917                 am.broadcastIntentWithFeature(null, null, intent, null, null,
22918                         0, null, null, null, null, android.app.AppOpsManager.OP_NONE,
22919                         null, false, false, userId);
22920             } catch (RemoteException e) {
22921             }
22922         });
22923     }
22924 
22925     @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)22926     public void replacePreferredActivity(IntentFilter filter, int match,
22927             ComponentName[] set, ComponentName activity, int userId) {
22928         replacePreferredActivity(new WatchedIntentFilter(filter), match,
22929                                  set, activity, userId);
22930     }
22931 
22932     /**
22933      * Variant that takes a {@link WatchedIntentFilter}
22934      */
replacePreferredActivity(WatchedIntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)22935     public void replacePreferredActivity(WatchedIntentFilter filter, int match,
22936             ComponentName[] set, ComponentName activity, int userId) {
22937         if (filter.countActions() != 1) {
22938             throw new IllegalArgumentException(
22939                     "replacePreferredActivity expects filter to have only 1 action.");
22940         }
22941         if (filter.countDataAuthorities() != 0
22942                 || filter.countDataPaths() != 0
22943                 || filter.countDataSchemes() > 1
22944                 || filter.countDataTypes() != 0) {
22945             throw new IllegalArgumentException(
22946                     "replacePreferredActivity expects filter to have no data authorities, " +
22947                     "paths, or types; and at most one scheme.");
22948         }
22949 
22950         final int callingUid = Binder.getCallingUid();
22951         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
22952                 false /* checkShell */, "replace preferred activity");
22953         if (mContext.checkCallingOrSelfPermission(
22954                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
22955                 != PackageManager.PERMISSION_GRANTED) {
22956             synchronized (mLock) {
22957                 if (getUidTargetSdkVersionLockedLPr(callingUid)
22958                         < Build.VERSION_CODES.FROYO) {
22959                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
22960                             + Binder.getCallingUid());
22961                     return;
22962                 }
22963             }
22964             mContext.enforceCallingOrSelfPermission(
22965                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
22966         }
22967 
22968         synchronized (mLock) {
22969             final PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
22970             if (pir != null) {
22971                 // Get all of the existing entries that exactly match this filter.
22972                 final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
22973                 if (existing != null && existing.size() == 1) {
22974                     final PreferredActivity cur = existing.get(0);
22975                     if (DEBUG_PREFERRED) {
22976                         Slog.i(TAG, "Checking replace of preferred:");
22977                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
22978                         if (!cur.mPref.mAlways) {
22979                             Slog.i(TAG, "  -- CUR; not mAlways!");
22980                         } else {
22981                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
22982                             Slog.i(TAG, "  -- CUR: mSet="
22983                                     + Arrays.toString(cur.mPref.mSetComponents));
22984                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
22985                             Slog.i(TAG, "  -- NEW: mMatch="
22986                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
22987                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
22988                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
22989                         }
22990                     }
22991                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
22992                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
22993                             && cur.mPref.sameSet(set)) {
22994                         // Setting the preferred activity to what it happens to be already
22995                         if (DEBUG_PREFERRED) {
22996                             Slog.i(TAG, "Replacing with same preferred activity "
22997                                     + cur.mPref.mShortComponent + " for user "
22998                                     + userId + ":");
22999                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
23000                         }
23001                         return;
23002                     }
23003                 }
23004                 if (existing != null) {
23005                     Settings.removeFilters(pir, filter, existing);
23006                 }
23007             }
23008         }
23009         addPreferredActivity(filter, match, set, activity, true, userId,
23010                 "Replacing preferred", false);
23011     }
23012 
23013     @Override
clearPackagePreferredActivities(String packageName)23014     public void clearPackagePreferredActivities(String packageName) {
23015         final int callingUid = Binder.getCallingUid();
23016         if (getInstantAppPackageName(callingUid) != null) {
23017             return;
23018         }
23019         // writer
23020         synchronized (mLock) {
23021             AndroidPackage pkg = mPackages.get(packageName);
23022             if (pkg == null || !isCallerSameApp(packageName, callingUid)) {
23023                 if (mContext.checkCallingOrSelfPermission(
23024                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
23025                         != PackageManager.PERMISSION_GRANTED) {
23026                     if (getUidTargetSdkVersionLockedLPr(callingUid)
23027                             < Build.VERSION_CODES.FROYO) {
23028                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
23029                                 + callingUid);
23030                         return;
23031                     }
23032                     mContext.enforceCallingOrSelfPermission(
23033                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
23034                 }
23035             }
23036             final PackageSetting ps = mSettings.getPackageLPr(packageName);
23037             if (ps != null
23038                     && shouldFilterApplicationLocked(
23039                             ps, callingUid, UserHandle.getUserId(callingUid))) {
23040                 return;
23041             }
23042         }
23043         int callingUserId = UserHandle.getCallingUserId();
23044         clearPackagePreferredActivities(packageName, callingUserId);
23045     }
23046 
23047     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearPackagePreferredActivities(String packageName, int userId)23048     private void clearPackagePreferredActivities(String packageName, int userId) {
23049         final SparseBooleanArray changedUsers = new SparseBooleanArray();
23050         synchronized (mLock) {
23051             clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId);
23052         }
23053         if (changedUsers.size() > 0) {
23054             updateDefaultHomeNotLocked(changedUsers);
23055             postPreferredActivityChangedBroadcast(userId);
23056             synchronized (mLock) {
23057                 scheduleWritePackageRestrictionsLocked(userId);
23058             }
23059         }
23060     }
23061 
23062     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
23063     @GuardedBy("mLock")
clearPackagePreferredActivitiesLPw(String packageName, @NonNull SparseBooleanArray outUserChanged, int userId)23064     private void clearPackagePreferredActivitiesLPw(String packageName,
23065             @NonNull SparseBooleanArray outUserChanged, int userId) {
23066         mSettings.clearPackagePreferredActivities(packageName, outUserChanged, userId);
23067     }
23068 
restorePermissionsAndUpdateRolesForNewUserInstall(String packageName, int installReason, @UserIdInt int userId)23069     private void restorePermissionsAndUpdateRolesForNewUserInstall(String packageName,
23070             int installReason, @UserIdInt int userId) {
23071         // We may also need to apply pending (restored) runtime permission grants
23072         // within these users.
23073         mPermissionManager.restoreDelayedRuntimePermissions(packageName, userId);
23074 
23075         // Persistent preferred activity might have came into effect due to this
23076         // install.
23077         updateDefaultHomeNotLocked(userId);
23078     }
23079 
23080     @Override
resetApplicationPreferences(int userId)23081     public void resetApplicationPreferences(int userId) {
23082         mContext.enforceCallingOrSelfPermission(
23083                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
23084         final long identity = Binder.clearCallingIdentity();
23085         // writer
23086         try {
23087             final SparseBooleanArray changedUsers = new SparseBooleanArray();
23088             synchronized (mLock) {
23089                 clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
23090             }
23091             if (changedUsers.size() > 0) {
23092                 postPreferredActivityChangedBroadcast(userId);
23093             }
23094             synchronized (mLock) {
23095                 mSettings.applyDefaultPreferredAppsLPw(userId);
23096                 mDomainVerificationManager.clearUser(userId);
23097                 final int numPackages = mPackages.size();
23098                 for (int i = 0; i < numPackages; i++) {
23099                     final AndroidPackage pkg = mPackages.valueAt(i);
23100                     mPermissionManager.resetRuntimePermissions(pkg, userId);
23101                 }
23102             }
23103             updateDefaultHomeNotLocked(userId);
23104             resetNetworkPolicies(userId);
23105             synchronized (mLock) {
23106                 scheduleWritePackageRestrictionsLocked(userId);
23107             }
23108         } finally {
23109             Binder.restoreCallingIdentity(identity);
23110         }
23111     }
23112 
23113     @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)23114     public int getPreferredActivities(List<IntentFilter> outFilters,
23115             List<ComponentName> outActivities, String packageName) {
23116         List<WatchedIntentFilter> temp =
23117                 WatchedIntentFilter.toWatchedIntentFilterList(outFilters);
23118         final int result = getPreferredActivitiesInternal(
23119                 temp, outActivities, packageName);
23120         outFilters.clear();
23121         for (int i = 0; i < temp.size(); i++) {
23122             outFilters.add(temp.get(i).getIntentFilter());
23123         }
23124         return result;
23125     }
23126 
23127     /**
23128      * Variant that takes a {@link WatchedIntentFilter}
23129      */
getPreferredActivitiesInternal(List<WatchedIntentFilter> outFilters, List<ComponentName> outActivities, String packageName)23130     public int getPreferredActivitiesInternal(List<WatchedIntentFilter> outFilters,
23131             List<ComponentName> outActivities, String packageName) {
23132         final int callingUid = Binder.getCallingUid();
23133         if (getInstantAppPackageName(callingUid) != null) {
23134             return 0;
23135         }
23136         int num = 0;
23137         final int userId = UserHandle.getCallingUserId();
23138         // reader
23139         synchronized (mLock) {
23140             PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
23141             if (pir != null) {
23142                 final Iterator<PreferredActivity> it = pir.filterIterator();
23143                 while (it.hasNext()) {
23144                     final PreferredActivity pa = it.next();
23145                     final String prefPackageName = pa.mPref.mComponent.getPackageName();
23146                     if (packageName == null
23147                             || (prefPackageName.equals(packageName) && pa.mPref.mAlways)) {
23148                         if (shouldFilterApplicationLocked(
23149                                 mSettings.getPackageLPr(prefPackageName), callingUid, userId)) {
23150                             continue;
23151                         }
23152                         if (outFilters != null) {
23153                             outFilters.add(new WatchedIntentFilter(pa.getIntentFilter()));
23154                         }
23155                         if (outActivities != null) {
23156                             outActivities.add(pa.mPref.mComponent);
23157                         }
23158                     }
23159                 }
23160             }
23161         }
23162 
23163         return num;
23164     }
23165 
23166     @Override
addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, int userId)23167     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
23168             int userId) {
23169         addPersistentPreferredActivity(new WatchedIntentFilter(filter), activity, userId);
23170     }
23171 
23172     /**
23173      * Variant that takes a {@link WatchedIntentFilter}
23174      */
addPersistentPreferredActivity(WatchedIntentFilter filter, ComponentName activity, int userId)23175     public void addPersistentPreferredActivity(WatchedIntentFilter filter, ComponentName activity,
23176             int userId) {
23177         int callingUid = Binder.getCallingUid();
23178         if (callingUid != Process.SYSTEM_UID) {
23179             throw new SecurityException(
23180                     "addPersistentPreferredActivity can only be run by the system");
23181         }
23182         if (filter.countActions() == 0) {
23183             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
23184             return;
23185         }
23186         if (DEBUG_PREFERRED) {
23187             Slog.i(TAG, "Adding persistent preferred activity " + activity
23188                     + " for user " + userId + ":");
23189             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
23190         }
23191         synchronized (mLock) {
23192             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
23193                     new PersistentPreferredActivity(filter, activity, true));
23194             scheduleWritePackageRestrictionsLocked(userId);
23195         }
23196         if (isHomeFilter(filter)) {
23197             updateDefaultHomeNotLocked(userId);
23198         }
23199         postPreferredActivityChangedBroadcast(userId);
23200     }
23201 
23202     @Override
clearPackagePersistentPreferredActivities(String packageName, int userId)23203     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
23204         int callingUid = Binder.getCallingUid();
23205         if (callingUid != Process.SYSTEM_UID) {
23206             throw new SecurityException(
23207                     "clearPackagePersistentPreferredActivities can only be run by the system");
23208         }
23209         boolean changed = false;
23210         synchronized (mLock) {
23211             changed = mSettings.clearPackagePersistentPreferredActivities(packageName, userId);
23212         }
23213         if (changed) {
23214             updateDefaultHomeNotLocked(userId);
23215             postPreferredActivityChangedBroadcast(userId);
23216             synchronized (mLock) {
23217                 scheduleWritePackageRestrictionsLocked(userId);
23218             }
23219         }
23220     }
23221 
23222     /**
23223      * Common machinery for picking apart a restored XML blob and passing
23224      * it to a caller-supplied functor to be applied to the running system.
23225      */
restoreFromXml(TypedXmlPullParser parser, int userId, String expectedStartTag, BlobXmlRestorer functor)23226     private void restoreFromXml(TypedXmlPullParser parser, int userId,
23227             String expectedStartTag, BlobXmlRestorer functor)
23228             throws IOException, XmlPullParserException {
23229         int type;
23230         while ((type = parser.next()) != XmlPullParser.START_TAG
23231                 && type != XmlPullParser.END_DOCUMENT) {
23232         }
23233         if (type != XmlPullParser.START_TAG) {
23234             // oops didn't find a start tag?!
23235             if (DEBUG_BACKUP) {
23236                 Slog.e(TAG, "Didn't find start tag during restore");
23237             }
23238             return;
23239         }
23240         // this is supposed to be TAG_PREFERRED_BACKUP
23241         if (!expectedStartTag.equals(parser.getName())) {
23242             if (DEBUG_BACKUP) {
23243                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
23244             }
23245             return;
23246         }
23247 
23248         // skip interfering stuff, then we're aligned with the backing implementation
23249         while ((type = parser.next()) == XmlPullParser.TEXT) { }
23250         functor.apply(parser, userId);
23251     }
23252 
23253     private interface BlobXmlRestorer {
apply(TypedXmlPullParser parser, int userId)23254         void apply(TypedXmlPullParser parser, int userId)
23255                 throws IOException, XmlPullParserException;
23256     }
23257 
23258     /**
23259      * Non-Binder method, support for the backup/restore mechanism: write the
23260      * full set of preferred activities in its canonical XML format.  Returns the
23261      * XML output as a byte array, or null if there is none.
23262      */
23263     @Override
getPreferredActivityBackup(int userId)23264     public byte[] getPreferredActivityBackup(int userId) {
23265         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23266             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
23267         }
23268 
23269         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
23270         try {
23271             final TypedXmlSerializer serializer = Xml.newFastSerializer();
23272             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
23273             serializer.startDocument(null, true);
23274             serializer.startTag(null, TAG_PREFERRED_BACKUP);
23275 
23276             synchronized (mLock) {
23277                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
23278             }
23279 
23280             serializer.endTag(null, TAG_PREFERRED_BACKUP);
23281             serializer.endDocument();
23282             serializer.flush();
23283         } catch (Exception e) {
23284             if (DEBUG_BACKUP) {
23285                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
23286             }
23287             return null;
23288         }
23289 
23290         return dataStream.toByteArray();
23291     }
23292 
23293     @Override
restorePreferredActivities(byte[] backup, int userId)23294     public void restorePreferredActivities(byte[] backup, int userId) {
23295         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23296             throw new SecurityException("Only the system may call restorePreferredActivities()");
23297         }
23298 
23299         try {
23300             final TypedXmlPullParser parser = Xml.newFastPullParser();
23301             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
23302             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
23303                     (readParser, readUserId) -> {
23304                         synchronized (mLock) {
23305                             mSettings.readPreferredActivitiesLPw(readParser, readUserId);
23306                         }
23307                         updateDefaultHomeNotLocked(readUserId);
23308                     });
23309         } catch (Exception e) {
23310             if (DEBUG_BACKUP) {
23311                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
23312             }
23313         }
23314     }
23315 
23316     /**
23317      * Non-Binder method, support for the backup/restore mechanism: write the
23318      * default browser (etc) settings in its canonical XML format.  Returns the default
23319      * browser XML representation as a byte array, or null if there is none.
23320      */
23321     @Override
getDefaultAppsBackup(int userId)23322     public byte[] getDefaultAppsBackup(int userId) {
23323         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23324             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
23325         }
23326 
23327         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
23328         try {
23329             final TypedXmlSerializer serializer = Xml.newFastSerializer();
23330             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
23331             serializer.startDocument(null, true);
23332             serializer.startTag(null, TAG_DEFAULT_APPS);
23333 
23334             synchronized (mLock) {
23335                 mSettings.writeDefaultAppsLPr(serializer, userId);
23336             }
23337 
23338             serializer.endTag(null, TAG_DEFAULT_APPS);
23339             serializer.endDocument();
23340             serializer.flush();
23341         } catch (Exception e) {
23342             if (DEBUG_BACKUP) {
23343                 Slog.e(TAG, "Unable to write default apps for backup", e);
23344             }
23345             return null;
23346         }
23347 
23348         return dataStream.toByteArray();
23349     }
23350 
23351     @Override
restoreDefaultApps(byte[] backup, int userId)23352     public void restoreDefaultApps(byte[] backup, int userId) {
23353         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23354             throw new SecurityException("Only the system may call restoreDefaultApps()");
23355         }
23356 
23357         try {
23358             final TypedXmlPullParser parser = Xml.newFastPullParser();
23359             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
23360             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
23361                     (parser1, userId1) -> {
23362                         final String defaultBrowser;
23363                         synchronized (mLock) {
23364                             mSettings.readDefaultAppsLPw(parser1, userId1);
23365                             defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
23366                         }
23367                         if (defaultBrowser != null) {
23368                             mDefaultAppProvider.setDefaultBrowser(defaultBrowser, false, userId1);
23369                         }
23370                     });
23371         } catch (Exception e) {
23372             if (DEBUG_BACKUP) {
23373                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
23374             }
23375         }
23376     }
23377 
23378     @Override
getDomainVerificationBackup(int userId)23379     public byte[] getDomainVerificationBackup(int userId) {
23380         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23381             throw new SecurityException("Only the system may call getDomainVerificationBackup()");
23382         }
23383 
23384         try {
23385             try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
23386                 TypedXmlSerializer serializer = Xml.resolveSerializer(output);
23387                 mDomainVerificationManager.writeSettings(serializer, true, userId);
23388                 return output.toByteArray();
23389             }
23390         } catch (Exception e) {
23391             if (DEBUG_BACKUP) {
23392                 Slog.e(TAG, "Unable to write domain verification for backup", e);
23393             }
23394             return null;
23395         }
23396     }
23397 
23398     @Override
restoreDomainVerification(byte[] backup, int userId)23399     public void restoreDomainVerification(byte[] backup, int userId) {
23400         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23401             throw new SecurityException("Only the system may call restorePreferredActivities()");
23402         }
23403 
23404         try {
23405             ByteArrayInputStream input = new ByteArrayInputStream(backup);
23406             TypedXmlPullParser parser = Xml.resolvePullParser(input);
23407 
23408             // User ID input isn't necessary here as it assumes the user integers match and that
23409             // the only states inside the backup XML are for the target user.
23410             mDomainVerificationManager.restoreSettings(parser);
23411             input.close();
23412         } catch (Exception e) {
23413             if (DEBUG_BACKUP) {
23414                 Slog.e(TAG, "Exception restoring domain verification: " + e.getMessage());
23415             }
23416         }
23417     }
23418 
23419     @Override
addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, int sourceUserId, int targetUserId, int flags)23420     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
23421             int sourceUserId, int targetUserId, int flags) {
23422         addCrossProfileIntentFilter(new WatchedIntentFilter(intentFilter), ownerPackage,
23423                                     sourceUserId, targetUserId, flags);
23424     }
23425 
23426     /**
23427      * Variant that takes a {@link WatchedIntentFilter}
23428      */
addCrossProfileIntentFilter(WatchedIntentFilter intentFilter, String ownerPackage, int sourceUserId, int targetUserId, int flags)23429     public void addCrossProfileIntentFilter(WatchedIntentFilter intentFilter, String ownerPackage,
23430             int sourceUserId, int targetUserId, int flags) {
23431         mContext.enforceCallingOrSelfPermission(
23432                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
23433         int callingUid = Binder.getCallingUid();
23434         enforceOwnerRights(ownerPackage, callingUid);
23435         PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
23436                 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
23437         if (intentFilter.countActions() == 0) {
23438             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
23439             return;
23440         }
23441         synchronized (mLock) {
23442             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
23443                     ownerPackage, targetUserId, flags);
23444             CrossProfileIntentResolver resolver =
23445                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
23446             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
23447             // We have all those whose filter is equal. Now checking if the rest is equal as well.
23448             if (existing != null) {
23449                 int size = existing.size();
23450                 for (int i = 0; i < size; i++) {
23451                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
23452                         return;
23453                     }
23454                 }
23455             }
23456             resolver.addFilter(newFilter);
23457             scheduleWritePackageRestrictionsLocked(sourceUserId);
23458         }
23459     }
23460 
23461     @Override
clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage)23462     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
23463         mContext.enforceCallingOrSelfPermission(
23464                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
23465         final int callingUid = Binder.getCallingUid();
23466         enforceOwnerRights(ownerPackage, callingUid);
23467         PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
23468                 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
23469         synchronized (mLock) {
23470             CrossProfileIntentResolver resolver =
23471                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
23472             ArraySet<CrossProfileIntentFilter> set =
23473                     new ArraySet<>(resolver.filterSet());
23474             for (CrossProfileIntentFilter filter : set) {
23475                 if (filter.getOwnerPackage().equals(ownerPackage)) {
23476                     resolver.removeFilter(filter);
23477                 }
23478             }
23479             scheduleWritePackageRestrictionsLocked(sourceUserId);
23480         }
23481     }
23482 
23483     // Enforcing that callingUid is owning pkg on userId
enforceOwnerRights(String pkg, int callingUid)23484     private void enforceOwnerRights(String pkg, int callingUid) {
23485         // The system owns everything.
23486         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
23487             return;
23488         }
23489         final String[] callerPackageNames = getPackagesForUid(callingUid);
23490         if (!ArrayUtils.contains(callerPackageNames, pkg)) {
23491             throw new SecurityException("Calling uid " + callingUid
23492                     + " does not own package " + pkg);
23493         }
23494         final int callingUserId = UserHandle.getUserId(callingUid);
23495         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
23496         if (pi == null) {
23497             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
23498                     + callingUserId);
23499         }
23500     }
23501 
23502     @Override
getHomeActivities(List<ResolveInfo> allHomeCandidates)23503     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
23504         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23505             return null;
23506         }
23507         return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
23508     }
23509 
23510     /**
23511      * Send a {@code PackageInstaller.ACTION_SESSION_UPDATED} broadcast intent, containing
23512      * the {@code sessionInfo} in the extra field {@code PackageInstaller.EXTRA_SESSION}.
23513      */
sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId)23514     public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo,
23515             int userId) {
23516         if (TextUtils.isEmpty(sessionInfo.installerPackageName)) {
23517             return;
23518         }
23519         Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED)
23520                 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
23521                 .setPackage(sessionInfo.installerPackageName);
23522         mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId));
23523     }
23524 
sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId)23525     public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
23526         UserManagerService ums = UserManagerService.getInstance();
23527         if (ums != null && !sessionInfo.isStaged()) {
23528             final UserInfo parent = ums.getProfileParent(userId);
23529             final int launcherUid = (parent != null) ? parent.id : userId;
23530             final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
23531             if (launcherComponent != null) {
23532                 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
23533                         .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
23534                         .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
23535                         .setPackage(launcherComponent.getPackageName());
23536                 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
23537             }
23538             // TODO(b/122900055) Change/Remove this and replace with new permission role.
23539             if (mAppPredictionServicePackage != null) {
23540                 Intent predictorIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
23541                         .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
23542                         .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
23543                         .setPackage(mAppPredictionServicePackage);
23544                 mContext.sendBroadcastAsUser(predictorIntent, UserHandle.of(launcherUid));
23545             }
23546         }
23547     }
23548 
23549     /**
23550      * Report the 'Home' activity which is currently set as "always use this one". If non is set
23551      * then reports the most likely home activity or null if there are more than one.
23552      */
getDefaultHomeActivity(int userId)23553     private ComponentName getDefaultHomeActivity(int userId) {
23554         return mComputer.getDefaultHomeActivity(userId);
23555     }
23556 
getHomeIntent()23557     private Intent getHomeIntent() {
23558         return mComputer.getHomeIntent();
23559     }
23560 
getHomeFilter()23561     private WatchedIntentFilter getHomeFilter() {
23562         WatchedIntentFilter filter = new WatchedIntentFilter(Intent.ACTION_MAIN);
23563         filter.addCategory(Intent.CATEGORY_HOME);
23564         filter.addCategory(Intent.CATEGORY_DEFAULT);
23565         return filter;
23566     }
23567 
isHomeFilter(@onNull WatchedIntentFilter filter)23568     private boolean isHomeFilter(@NonNull WatchedIntentFilter filter) {
23569         return filter.hasAction(Intent.ACTION_MAIN) && filter.hasCategory(Intent.CATEGORY_HOME)
23570                 && filter.hasCategory(CATEGORY_DEFAULT);
23571     }
23572 
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)23573     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23574             int userId) {
23575         return mComputer.getHomeActivitiesAsUser(allHomeCandidates,
23576                 userId);
23577     }
23578 
23579     /** <b>must not hold {@link #mLock}</b> */
updateDefaultHomeNotLocked(SparseBooleanArray userIds)23580     private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
23581         if (Thread.holdsLock(mLock)) {
23582             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
23583                     + " is holding mLock", new Throwable());
23584         }
23585         for (int i = userIds.size() - 1; i >= 0; --i) {
23586             final int userId = userIds.keyAt(i);
23587             updateDefaultHomeNotLocked(userId);
23588         }
23589     }
23590 
23591     /**
23592      * <b>must not hold {@link #mLock}</b>
23593      *
23594      * @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
23595      */
updateDefaultHomeNotLocked(int userId)23596     private boolean updateDefaultHomeNotLocked(int userId) {
23597         if (Thread.holdsLock(mLock)) {
23598             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
23599                     + " is holding mLock", new Throwable());
23600         }
23601         if (!mSystemReady) {
23602             // We might get called before system is ready because of package changes etc, but
23603             // finding preferred activity depends on settings provider, so we ignore the update
23604             // before that.
23605             return false;
23606         }
23607         final Intent intent = getHomeIntent();
23608         final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
23609                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
23610         final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
23611                 intent, null, 0, resolveInfos, 0, true, false, false, userId);
23612         final String packageName = preferredResolveInfo != null
23613                 && preferredResolveInfo.activityInfo != null
23614                 ? preferredResolveInfo.activityInfo.packageName : null;
23615         final String currentPackageName = mDefaultAppProvider.getDefaultHome(userId);
23616         if (TextUtils.equals(currentPackageName, packageName)) {
23617             return false;
23618         }
23619         final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
23620         if (callingPackages != null && ArrayUtils.contains(callingPackages,
23621                 mRequiredPermissionControllerPackage)) {
23622             // PermissionController manages default home directly.
23623             return false;
23624         }
23625 
23626         if (packageName == null) {
23627             // Keep the default home package in RoleManager.
23628             return false;
23629         }
23630         return mDefaultAppProvider.setDefaultHome(packageName, userId, mContext.getMainExecutor(),
23631                 successful -> {
23632                     if (successful) {
23633                         postPreferredActivityChangedBroadcast(userId);
23634                     }
23635                 });
23636     }
23637 
23638     @Override
23639     public void setHomeActivity(ComponentName comp, int userId) {
23640         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23641             return;
23642         }
23643         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
23644         getHomeActivitiesAsUser(homeActivities, userId);
23645 
23646         boolean found = false;
23647 
23648         final int size = homeActivities.size();
23649         final ComponentName[] set = new ComponentName[size];
23650         for (int i = 0; i < size; i++) {
23651             final ResolveInfo candidate = homeActivities.get(i);
23652             final ActivityInfo info = candidate.activityInfo;
23653             final ComponentName activityName = new ComponentName(info.packageName, info.name);
23654             set[i] = activityName;
23655             if (!found && activityName.equals(comp)) {
23656                 found = true;
23657             }
23658         }
23659         if (!found) {
23660             throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
23661                     + userId);
23662         }
23663         replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
23664                 set, comp, userId);
23665     }
23666 
23667     private @Nullable String getSetupWizardPackageNameImpl() {
23668         final Intent intent = new Intent(Intent.ACTION_MAIN);
23669         intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
23670 
23671         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
23672                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
23673                         | MATCH_DISABLED_COMPONENTS,
23674                 UserHandle.myUserId());
23675         if (matches.size() == 1) {
23676             return matches.get(0).getComponentInfo().packageName;
23677         } else {
23678             Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
23679                     + ": matches=" + matches);
23680             return null;
23681         }
23682     }
23683 
23684     private @Nullable String getStorageManagerPackageName() {
23685         final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
23686 
23687         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
23688                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
23689                         | MATCH_DISABLED_COMPONENTS,
23690                 UserHandle.myUserId());
23691         if (matches.size() == 1) {
23692             return matches.get(0).getComponentInfo().packageName;
23693         } else {
23694             Slog.w(TAG, "There should probably be exactly one storage manager; found "
23695                     + matches.size() + ": matches=" + matches);
23696             return null;
23697         }
23698     }
23699 
23700     @Override
23701     public String getDefaultTextClassifierPackageName() {
23702         return ensureSystemPackageName(
23703                 mContext.getString(R.string.config_servicesExtensionPackage));
23704     }
23705 
23706     @Override
23707     public String getSystemTextClassifierPackageName() {
23708         return ensureSystemPackageName(
23709                 mContext.getString(R.string.config_defaultTextClassifierPackage));
23710     }
23711 
23712     @Override
23713     public @Nullable String getAttentionServicePackageName() {
23714         return ensureSystemPackageName(
23715                 getPackageFromComponentString(R.string.config_defaultAttentionService));
23716     }
23717 
23718     @Override
23719     public @Nullable String getRotationResolverPackageName() {
23720         return ensureSystemPackageName(
23721                 getPackageFromComponentString(R.string.config_defaultRotationResolverService));
23722     }
23723 
23724     private @Nullable String getDocumenterPackageName() {
23725         final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
23726         intent.addCategory(Intent.CATEGORY_OPENABLE);
23727         intent.setType("*/*");
23728         final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23729 
23730         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, resolvedType,
23731                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
23732                         | MATCH_DISABLED_COMPONENTS,
23733                 UserHandle.myUserId());
23734         if (matches.size() == 1) {
23735             return matches.get(0).getComponentInfo().packageName;
23736         } else {
23737             Slog.e(TAG, "There should probably be exactly one documenter; found "
23738                     + matches.size() + ": matches=" + matches);
23739             return null;
23740         }
23741     }
23742 
23743     @Nullable
23744     private String getDeviceConfiguratorPackageName() {
23745         return ensureSystemPackageName(mContext.getString(
23746                 R.string.config_deviceConfiguratorPackageName));
23747     }
23748 
23749     @Override
23750     public String getWellbeingPackageName() {
23751         final long identity = Binder.clearCallingIdentity();
23752         try {
23753             return CollectionUtils.firstOrNull(
23754                     mContext.getSystemService(RoleManager.class).getRoleHolders(
23755                             RoleManager.ROLE_SYSTEM_WELLBEING));
23756         } finally {
23757             Binder.restoreCallingIdentity(identity);
23758         }
23759     }
23760 
23761     @Override
23762     public String getAppPredictionServicePackageName() {
23763         return ensureSystemPackageName(
23764                 getPackageFromComponentString(R.string.config_defaultAppPredictionService));
23765     }
23766 
23767     @Override
23768     public String getSystemCaptionsServicePackageName() {
23769         return ensureSystemPackageName(
23770                 getPackageFromComponentString(R.string.config_defaultSystemCaptionsService));
23771     }
23772 
23773     @Override
23774     public String getSetupWizardPackageName() {
23775         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23776             throw new SecurityException("Non-system caller");
23777         }
23778         return mPmInternal.getSetupWizardPackageName();
23779     }
23780 
23781     public String getIncidentReportApproverPackageName() {
23782         return ensureSystemPackageName(mContext.getString(
23783                 R.string.config_incidentReportApproverPackage));
23784     }
23785 
23786     @Override
23787     public String getContentCaptureServicePackageName() {
23788         return ensureSystemPackageName(
23789                 getPackageFromComponentString(R.string.config_defaultContentCaptureService));
23790     }
23791 
23792     public String getOverlayConfigSignaturePackageName() {
23793         return ensureSystemPackageName(mInjector.getSystemConfig()
23794                 .getOverlayConfigSignaturePackage());
23795     }
23796 
23797     @Nullable
23798     private String getRetailDemoPackageName() {
23799         final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
23800         final String predefinedSignature = mContext.getString(
23801                 R.string.config_retailDemoPackageSignature);
23802 
23803         if (TextUtils.isEmpty(predefinedPkgName) || TextUtils.isEmpty(predefinedSignature)) {
23804             return null;
23805         }
23806 
23807         final AndroidPackage androidPkg = mPackages.get(predefinedPkgName);
23808         if (androidPkg != null) {
23809             final SigningDetails signingDetail = androidPkg.getSigningDetails();
23810             if (signingDetail != null && signingDetail.signatures != null) {
23811                 try {
23812                     final MessageDigest msgDigest = MessageDigest.getInstance("SHA-256");
23813                     for (Signature signature : signingDetail.signatures) {
23814                         if (TextUtils.equals(predefinedSignature,
23815                                 HexEncoding.encodeToString(msgDigest.digest(
23816                                         signature.toByteArray()), false))) {
23817                             return predefinedPkgName;
23818                         }
23819                     }
23820                 } catch (NoSuchAlgorithmException e) {
23821                     Slog.e(
23822                             TAG,
23823                             "Unable to verify signatures as getting the retail demo package name",
23824                             e);
23825                 }
23826             }
23827         }
23828 
23829         return null;
23830     }
23831 
23832     @Nullable
23833     private String getRecentsPackageName() {
23834         return ensureSystemPackageName(
23835                 getPackageFromComponentString(R.string.config_recentsComponentName));
23836 
23837     }
23838 
23839     @Nullable
23840     private String getPackageFromComponentString(@StringRes int stringResId) {
23841         final String componentString = mContext.getString(stringResId);
23842         if (TextUtils.isEmpty(componentString)) {
23843             return null;
23844         }
23845         final ComponentName component = ComponentName.unflattenFromString(componentString);
23846         if (component == null) {
23847             return null;
23848         }
23849         return component.getPackageName();
23850     }
23851 
23852     @Nullable
23853     private String ensureSystemPackageName(@Nullable String packageName) {
23854         if (packageName == null) {
23855             return null;
23856         }
23857         final long token = Binder.clearCallingIdentity();
23858         try {
23859             if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
23860                 PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
23861                 if (packageInfo != null) {
23862                     EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
23863                             "");
23864                 }
23865                 return null;
23866             }
23867         } finally {
23868             Binder.restoreCallingIdentity(token);
23869         }
23870         return packageName;
23871     }
23872 
23873     @Nullable
23874     private String[] ensureSystemPackageNames(@Nullable String[] packageNames) {
23875         if (packageNames == null) {
23876             return null;
23877         }
23878         final int packageNamesLength = packageNames.length;
23879         for (int i = 0; i < packageNamesLength; i++) {
23880             packageNames[i] = ensureSystemPackageName(packageNames[i]);
23881         }
23882         return ArrayUtils.filterNotNull(packageNames, String[]::new);
23883     }
23884 
23885     @Override
23886     public void setApplicationEnabledSetting(String appPackageName,
23887             int newState, int flags, int userId, String callingPackage) {
23888         if (!mUserManager.exists(userId)) return;
23889         if (callingPackage == null) {
23890             callingPackage = Integer.toString(Binder.getCallingUid());
23891         }
23892         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
23893     }
23894 
23895     @Override
23896     public void setUpdateAvailable(String packageName, boolean updateAvailable) {
23897         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
23898         synchronized (mLock) {
23899             final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
23900             if (pkgSetting != null) {
23901                 pkgSetting.setUpdateAvailable(updateAvailable);
23902             }
23903         }
23904     }
23905 
23906     @Override
23907     public void overrideLabelAndIcon(@NonNull ComponentName componentName,
23908             @NonNull String nonLocalizedLabel, int icon, int userId) {
23909         if (TextUtils.isEmpty(nonLocalizedLabel)) {
23910             throw new IllegalArgumentException("Override label should be a valid String");
23911         }
23912         updateComponentLabelIcon(componentName, nonLocalizedLabel, icon, userId);
23913     }
23914 
23915     @Override
23916     public void restoreLabelAndIcon(@NonNull ComponentName componentName, int userId) {
23917         updateComponentLabelIcon(componentName, null, null, userId);
23918     }
23919 
23920     @VisibleForTesting(visibility = Visibility.PRIVATE)
23921     public void updateComponentLabelIcon(/*@NonNull*/ ComponentName componentName,
23922             @Nullable String nonLocalizedLabel, @Nullable Integer icon, int userId) {
23923         if (componentName == null) {
23924             throw new IllegalArgumentException("Must specify a component");
23925         }
23926 
23927         int callingUid = Binder.getCallingUid();
23928 
23929         String componentPkgName = componentName.getPackageName();
23930         int componentUid = getPackageUid(componentPkgName, 0, userId);
23931         if (!UserHandle.isSameApp(callingUid, componentUid)) {
23932             throw new SecurityException("The calling UID (" + callingUid + ")"
23933                     + " does not match the target UID");
23934         }
23935 
23936         String allowedCallerPkg = mContext.getString(R.string.config_overrideComponentUiPackage);
23937         if (TextUtils.isEmpty(allowedCallerPkg)) {
23938             throw new SecurityException(
23939                     "There is no package defined as allowed to change a component's label or icon");
23940         }
23941 
23942         int allowedCallerUid = getPackageUid(allowedCallerPkg, PackageManager.MATCH_SYSTEM_ONLY,
23943                 userId);
23944         if (allowedCallerUid == -1 || !UserHandle.isSameApp(callingUid, allowedCallerUid)) {
23945             throw new SecurityException("The calling UID (" + callingUid + ")"
23946                     + " is not allowed to change a component's label or icon");
23947         }
23948 
23949         synchronized (mLock) {
23950             AndroidPackage pkg = mPackages.get(componentPkgName);
23951             PackageSetting pkgSetting = getPackageSetting(componentPkgName);
23952             if (pkg == null || pkgSetting == null
23953                     || (!pkg.isSystem() && !pkgSetting.getPkgState().isUpdatedSystemApp())) {
23954                 throw new SecurityException(
23955                         "Changing the label is not allowed for " + componentName);
23956             }
23957 
23958             if (!mComponentResolver.componentExists(componentName)) {
23959                 throw new IllegalArgumentException("Component " + componentName + " not found");
23960             }
23961 
23962             if (!pkgSetting.overrideNonLocalizedLabelAndIcon(componentName, nonLocalizedLabel,
23963                     icon, userId)) {
23964                 // Nothing changed
23965                 return;
23966             }
23967         }
23968 
23969         ArrayList<String> components = mPendingBroadcasts.get(userId, componentPkgName);
23970         if (components == null) {
23971             components = new ArrayList<>();
23972             mPendingBroadcasts.put(userId, componentPkgName, components);
23973         }
23974 
23975         String className = componentName.getClassName();
23976         if (!components.contains(className)) {
23977             components.add(className);
23978         }
23979 
23980         if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
23981             mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
23982         }
23983     }
23984 
23985     @Override
23986     public void setComponentEnabledSetting(ComponentName componentName,
23987             int newState, int flags, int userId) {
23988         if (!mUserManager.exists(userId)) return;
23989         setEnabledSetting(componentName.getPackageName(),
23990                 componentName.getClassName(), newState, flags, userId, null);
23991     }
23992 
23993     private void setEnabledSetting(final String packageName, String className, int newState,
23994             final int flags, int userId, String callingPackage) {
23995         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
23996               || newState == COMPONENT_ENABLED_STATE_ENABLED
23997               || newState == COMPONENT_ENABLED_STATE_DISABLED
23998               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
23999               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
24000             throw new IllegalArgumentException("Invalid new component state: "
24001                     + newState);
24002         }
24003         PackageSetting pkgSetting;
24004         final int callingUid = Binder.getCallingUid();
24005         final int permission;
24006         if (callingUid == Process.SYSTEM_UID) {
24007             permission = PackageManager.PERMISSION_GRANTED;
24008         } else {
24009             permission = mContext.checkCallingOrSelfPermission(
24010                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
24011         }
24012         enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
24013                 true /* checkShell */, "set enabled");
24014         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
24015         boolean sendNow = false;
24016         boolean isApp = (className == null);
24017         final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
24018         String componentName = isApp ? packageName : className;
24019         ArrayList<String> components;
24020 
24021         // reader
24022         synchronized (mLock) {
24023             pkgSetting = mSettings.getPackageLPr(packageName);
24024             if (pkgSetting == null) {
24025                 if (!isCallerInstantApp) {
24026                     if (className == null) {
24027                         throw new IllegalArgumentException("Unknown package: " + packageName);
24028                     }
24029                     throw new IllegalArgumentException(
24030                             "Unknown component: " + packageName + "/" + className);
24031                 } else {
24032                     // throw SecurityException to prevent leaking package information
24033                     throw new SecurityException(
24034                             "Attempt to change component state; "
24035                             + "pid=" + Binder.getCallingPid()
24036                             + ", uid=" + callingUid
24037                             + (className == null
24038                                     ? ", package=" + packageName
24039                                     : ", component=" + packageName + "/" + className));
24040                 }
24041             }
24042         }
24043 
24044         // Limit who can change which apps
24045         if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
24046             // Don't allow apps that don't have permission to modify other apps
24047             final boolean filterApp;
24048             synchronized (mLock) {
24049                 filterApp = (!allowedByPermission
24050                         || shouldFilterApplicationLocked(pkgSetting, callingUid, userId));
24051             }
24052             if (filterApp) {
24053                 throw new SecurityException(
24054                         "Attempt to change component state; "
24055                                 + "pid=" + Binder.getCallingPid()
24056                                 + ", uid=" + callingUid
24057                                 + (className == null
24058                                 ? ", package=" + packageName
24059                                         : ", component=" + packageName + "/" + className));
24060             }
24061             // Don't allow changing protected packages.
24062             if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
24063                 throw new SecurityException("Cannot disable a protected package: " + packageName);
24064             }
24065         }
24066         // Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden
24067         // app details activity
24068         if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)
24069                 && !allowedByPermission) {
24070             throw new SecurityException("Cannot disable a system-generated component");
24071         }
24072 
24073         synchronized (mLock) {
24074             if (callingUid == Process.SHELL_UID
24075                     && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
24076                 // Shell can only change whole packages between ENABLED and DISABLED_USER states
24077                 // unless it is a test package.
24078                 int oldState = pkgSetting.getEnabled(userId);
24079                 if (className == null
24080                         &&
24081                         (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
24082                                 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
24083                                 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
24084                         &&
24085                         (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
24086                                 || newState == COMPONENT_ENABLED_STATE_DEFAULT
24087                                 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
24088                     // ok
24089                 } else {
24090                     throw new SecurityException(
24091                             "Shell cannot change component state for " + packageName + "/"
24092                                     + className + " to " + newState);
24093                 }
24094             }
24095         }
24096         if (className == null) {
24097             // We're dealing with an application/package level state change
24098             synchronized (mLock) {
24099                 if (pkgSetting.getEnabled(userId) == newState) {
24100                     // Nothing to do
24101                     return;
24102                 }
24103             }
24104             // If we're enabling a system stub, there's a little more work to do.
24105             // Prior to enabling the package, we need to decompress the APK(s) to the
24106             // data partition and then replace the version on the system partition.
24107             final AndroidPackage deletedPkg = pkgSetting.pkg;
24108             final boolean isSystemStub = (deletedPkg != null)
24109                     && deletedPkg.isStub()
24110                     && deletedPkg.isSystem();
24111             if (isSystemStub
24112                     && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
24113                             || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
24114                 if (!enableCompressedPackage(deletedPkg, pkgSetting)) {
24115                     return;
24116                 }
24117             }
24118             if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
24119                 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
24120                 // Don't care about who enables an app.
24121                 callingPackage = null;
24122             }
24123             synchronized (mLock) {
24124                 pkgSetting.setEnabled(newState, userId, callingPackage);
24125                 if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER
24126                         || newState == COMPONENT_ENABLED_STATE_DISABLED)
24127                         && checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
24128                         == PERMISSION_GRANTED) {
24129                     // This app should not generally be allowed to get disabled by the UI, but if it
24130                     // ever does, we don't want to end up with some of the user's apps permanently
24131                     // suspended.
24132                     unsuspendForSuspendingPackage(packageName, userId);
24133                     removeAllDistractingPackageRestrictions(userId);
24134                 }
24135             }
24136         } else {
24137             synchronized (mLock) {
24138                 // We're dealing with a component level state change
24139                 // First, verify that this is a valid class name.
24140                 AndroidPackage pkg = pkgSetting.pkg;
24141                 if (pkg == null || !AndroidPackageUtils.hasComponentClassName(pkg, className)) {
24142                     if (pkg != null &&
24143                             pkg.getTargetSdkVersion() >=
24144                                     Build.VERSION_CODES.JELLY_BEAN) {
24145                         throw new IllegalArgumentException("Component class " + className
24146                                 + " does not exist in " + packageName);
24147                     } else {
24148                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
24149                                 + className + " does not exist in " + packageName);
24150                     }
24151                 }
24152                 switch (newState) {
24153                     case COMPONENT_ENABLED_STATE_ENABLED:
24154                         if (!pkgSetting.enableComponentLPw(className, userId)) {
24155                             return;
24156                         }
24157                         break;
24158                     case COMPONENT_ENABLED_STATE_DISABLED:
24159                         if (!pkgSetting.disableComponentLPw(className, userId)) {
24160                             return;
24161                         }
24162                         break;
24163                     case COMPONENT_ENABLED_STATE_DEFAULT:
24164                         if (!pkgSetting.restoreComponentLPw(className, userId)) {
24165                             return;
24166                         }
24167                         break;
24168                     default:
24169                         Slog.e(TAG, "Invalid new component state: " + newState);
24170                         return;
24171                 }
24172             }
24173         }
24174         synchronized (mLock) {
24175             if ((flags & PackageManager.SYNCHRONOUS) != 0) {
24176                 flushPackageRestrictionsAsUserInternalLocked(userId);
24177             } else {
24178                 scheduleWritePackageRestrictionsLocked(userId);
24179             }
24180             updateSequenceNumberLP(pkgSetting, new int[] { userId });
24181             final long callingId = Binder.clearCallingIdentity();
24182             try {
24183                 updateInstantAppInstallerLocked(packageName);
24184             } finally {
24185                 Binder.restoreCallingIdentity(callingId);
24186             }
24187             components = mPendingBroadcasts.get(userId, packageName);
24188             final boolean newPackage = components == null;
24189             if (newPackage) {
24190                 components = new ArrayList<>();
24191             }
24192             if (!components.contains(componentName)) {
24193                 components.add(componentName);
24194             }
24195             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
24196                 sendNow = true;
24197                 // Purge entry from pending broadcast list if another one exists already
24198                 // since we are sending one right away.
24199                 mPendingBroadcasts.remove(userId, packageName);
24200             } else {
24201                 if (newPackage) {
24202                     mPendingBroadcasts.put(userId, packageName, components);
24203                 }
24204                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
24205                     // Schedule a message - if it has been a "reasonably long time" since the
24206                     // service started, send the broadcast with a delay of one second to avoid
24207                     // delayed reactions from the receiver, else keep the default ten second delay
24208                     // to avoid extreme thrashing on service startup.
24209                     final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
24210                                                 ? BROADCAST_DELAY
24211                                                 : BROADCAST_DELAY_DURING_STARTUP;
24212                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
24213                 }
24214             }
24215         }
24216 
24217         final long callingId = Binder.clearCallingIdentity();
24218         try {
24219             if (sendNow) {
24220                 int packageUid = UserHandle.getUid(userId, pkgSetting.appId);
24221                 sendPackageChangedBroadcast(packageName,
24222                         (flags & PackageManager.DONT_KILL_APP) != 0, components, packageUid, null);
24223             }
24224         } finally {
24225             Binder.restoreCallingIdentity(callingId);
24226         }
24227     }
24228 
24229     @WorkerThread
24230     @Override
24231     public void flushPackageRestrictionsAsUser(int userId) {
24232         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24233             return;
24234         }
24235         if (!mUserManager.exists(userId)) {
24236             return;
24237         }
24238         enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
24239                 false /* checkShell */, "flushPackageRestrictions");
24240         synchronized (mLock) {
24241             flushPackageRestrictionsAsUserInternalLocked(userId);
24242         }
24243     }
24244 
24245     @GuardedBy("mLock")
24246     private void flushPackageRestrictionsAsUserInternalLocked(int userId) {
24247         // NOTE: this invokes synchronous disk access, so callers using this
24248         // method should consider running on a background thread
24249         mSettings.writePackageRestrictionsLPr(userId);
24250         mDirtyUsers.remove(userId);
24251         if (mDirtyUsers.isEmpty()) {
24252             mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
24253         }
24254     }
24255 
24256     private void sendPackageChangedBroadcast(String packageName,
24257             boolean dontKillApp, ArrayList<String> componentNames, int packageUid, String reason) {
24258         if (DEBUG_INSTALL)
24259             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
24260                     + componentNames);
24261         Bundle extras = new Bundle(4);
24262         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
24263         String nameList[] = new String[componentNames.size()];
24264         componentNames.toArray(nameList);
24265         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
24266         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, dontKillApp);
24267         extras.putInt(Intent.EXTRA_UID, packageUid);
24268         if (reason != null) {
24269             extras.putString(Intent.EXTRA_REASON, reason);
24270         }
24271         // If this is not reporting a change of the overall package, then only send it
24272         // to registered receivers.  We don't want to launch a swath of apps for every
24273         // little component state change.
24274         final int flags = !componentNames.contains(packageName)
24275                 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
24276         final int userId = UserHandle.getUserId(packageUid);
24277         final boolean isInstantApp = isInstantApp(packageName, userId);
24278         final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
24279         final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
24280         final SparseArray<int[]> broadcastAllowList;
24281         synchronized (mLock) {
24282             PackageSetting setting = getPackageSettingInternal(packageName, Process.SYSTEM_UID);
24283             if (setting == null) {
24284                 return;
24285             }
24286             broadcastAllowList = isInstantApp ? null : mAppsFilter.getVisibilityAllowList(setting,
24287                     userIds, mSettings.getPackagesLocked());
24288         }
24289         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
24290                 userIds, instantUserIds, broadcastAllowList, null);
24291     }
24292 
24293     @Override
24294     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
24295         if (!mUserManager.exists(userId)) return;
24296         final int callingUid = Binder.getCallingUid();
24297         if (getInstantAppPackageName(callingUid) != null) {
24298             return;
24299         }
24300         final int permission = mContext.checkCallingOrSelfPermission(
24301                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
24302         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
24303         if (!allowedByPermission
24304                 && !ArrayUtils.contains(getPackagesForUid(callingUid), packageName)) {
24305             throw new SecurityException(
24306                     "Permission Denial: attempt to change stopped state from pid="
24307                             + Binder.getCallingPid()
24308                             + ", uid=" + callingUid + ", package=" + packageName);
24309         }
24310         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
24311                 true /* checkShell */, "stop package");
24312         // writer
24313         synchronized (mLock) {
24314             final PackageSetting ps = mSettings.getPackageLPr(packageName);
24315             if (!shouldFilterApplicationLocked(ps, callingUid, userId)
24316                     && mSettings.setPackageStoppedStateLPw(this, packageName, stopped, userId)) {
24317                 scheduleWritePackageRestrictionsLocked(userId);
24318             }
24319         }
24320         // If this would cause the app to leave force-stop, then also make sure to unhibernate the
24321         // app if needed.
24322         if (!stopped) {
24323             mHandler.post(() -> {
24324                 AppHibernationManagerInternal ah =
24325                         mInjector.getLocalService(AppHibernationManagerInternal.class);
24326                 if (ah != null && ah.isHibernatingForUser(packageName, userId)) {
24327                     ah.setHibernatingForUser(packageName, userId, false);
24328                     ah.setHibernatingGlobally(packageName, false);
24329                 }
24330             });
24331         }
24332     }
24333 
24334     @Override
24335     public String getInstallerPackageName(String packageName) {
24336         final int callingUid = Binder.getCallingUid();
24337         synchronized (mLock) {
24338             final InstallSource installSource = getInstallSourceLocked(packageName, callingUid);
24339             if (installSource == null) {
24340                 throw new IllegalArgumentException("Unknown package: " + packageName);
24341             }
24342             String installerPackageName = installSource.installerPackageName;
24343             if (installerPackageName != null) {
24344                 final PackageSetting ps = mSettings.getPackageLPr(installerPackageName);
24345                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
24346                         UserHandle.getUserId(callingUid))) {
24347                     installerPackageName = null;
24348                 }
24349             }
24350             return installerPackageName;
24351         }
24352     }
24353 
24354     @Override
24355     @Nullable
24356     public InstallSourceInfo getInstallSourceInfo(String packageName) {
24357         final int callingUid = Binder.getCallingUid();
24358         final int userId = UserHandle.getUserId(callingUid);
24359 
24360         String installerPackageName;
24361         String initiatingPackageName;
24362         String originatingPackageName;
24363 
24364         final InstallSource installSource;
24365         synchronized (mLock) {
24366             installSource = getInstallSourceLocked(packageName, callingUid);
24367             if (installSource == null) {
24368                 return null;
24369             }
24370 
24371             installerPackageName = installSource.installerPackageName;
24372             if (installerPackageName != null) {
24373                 final PackageSetting ps = mSettings.getPackageLPr(installerPackageName);
24374                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
24375                     installerPackageName = null;
24376                 }
24377             }
24378 
24379             if (installSource.isInitiatingPackageUninstalled) {
24380                 // We can't check visibility in the usual way, since the initiating package is no
24381                 // longer present. So we apply simpler rules to whether to expose the info:
24382                 // 1. Instant apps can't see it.
24383                 // 2. Otherwise only the installed app itself can see it.
24384                 final boolean isInstantApp = getInstantAppPackageName(callingUid) != null;
24385                 if (!isInstantApp && isCallerSameApp(packageName, callingUid)) {
24386                     initiatingPackageName = installSource.initiatingPackageName;
24387                 } else {
24388                     initiatingPackageName = null;
24389                 }
24390             } else {
24391                 // All installSource strings are interned, so == is ok here
24392                 if (installSource.initiatingPackageName == installSource.installerPackageName) {
24393                     // The installer and initiator will often be the same, and when they are
24394                     // we can skip doing the same check again.
24395                     initiatingPackageName = installerPackageName;
24396                 } else {
24397                     initiatingPackageName = installSource.initiatingPackageName;
24398                     final PackageSetting ps = mSettings.getPackageLPr(initiatingPackageName);
24399                     if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
24400                         initiatingPackageName = null;
24401                     }
24402                 }
24403             }
24404 
24405             originatingPackageName = installSource.originatingPackageName;
24406             if (originatingPackageName != null) {
24407                 final PackageSetting ps = mSettings.getPackageLPr(originatingPackageName);
24408                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
24409                     originatingPackageName = null;
24410                 }
24411             }
24412         }
24413 
24414         // Remaining work can safely be done outside the lock. (Note that installSource is
24415         // immutable so it's ok to carry on reading from it.)
24416 
24417         if (originatingPackageName != null && mContext.checkCallingOrSelfPermission(
24418                 Manifest.permission.INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
24419             originatingPackageName = null;
24420         }
24421 
24422         // If you can see the initiatingPackageName, and we have valid signing info for it,
24423         // then we let you see that too.
24424         final SigningInfo initiatingPackageSigningInfo;
24425         final PackageSignatures signatures = installSource.initiatingPackageSignatures;
24426         if (initiatingPackageName != null && signatures != null
24427                 && signatures.mSigningDetails != SigningDetails.UNKNOWN) {
24428             initiatingPackageSigningInfo = new SigningInfo(signatures.mSigningDetails);
24429         } else {
24430             initiatingPackageSigningInfo = null;
24431         }
24432 
24433         return new InstallSourceInfo(initiatingPackageName, initiatingPackageSigningInfo,
24434                 originatingPackageName, installerPackageName);
24435     }
24436 
24437     @GuardedBy("mLock")
24438     @Nullable
24439     private InstallSource getInstallSourceLocked(String packageName, int callingUid) {
24440         final PackageSetting ps = mSettings.getPackageLPr(packageName);
24441 
24442         // Installer info for Apex is not stored in PackageManager
24443         if (ps == null && mApexManager.isApexPackage(packageName)) {
24444             return InstallSource.EMPTY;
24445         }
24446 
24447         if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
24448                 UserHandle.getUserId(callingUid))) {
24449             return null;
24450         }
24451 
24452         return ps.installSource;
24453     }
24454 
24455     public boolean isOrphaned(String packageName) {
24456         // reader
24457         synchronized (mLock) {
24458             if (!mPackages.containsKey(packageName)) {
24459                 return false;
24460             }
24461             return mSettings.isOrphaned(packageName);
24462         }
24463     }
24464 
24465     @Override
24466     public int getApplicationEnabledSetting(String packageName, int userId) {
24467         if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
24468         int callingUid = Binder.getCallingUid();
24469         enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
24470                 false /* checkShell */, "get enabled");
24471         // reader
24472         synchronized (mLock) {
24473             try {
24474                 if (shouldFilterApplicationLocked(
24475                         mSettings.getPackageLPr(packageName), callingUid, userId)) {
24476                     throw new PackageManager.NameNotFoundException(packageName);
24477                 }
24478                 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
24479             } catch (PackageManager.NameNotFoundException e) {
24480                 throw new IllegalArgumentException("Unknown package: " + packageName);
24481             }
24482         }
24483     }
24484 
24485     @Override
24486     public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
24487         int callingUid = Binder.getCallingUid();
24488         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
24489                 false /*checkShell*/, "getComponentEnabled");
24490         return getComponentEnabledSettingInternal(component, callingUid, userId);
24491     }
24492 
24493     private int getComponentEnabledSettingInternal(ComponentName component, int callingUid,
24494             int userId) {
24495         if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
24496         if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
24497 
24498         synchronized (mLock) {
24499             try {
24500                 if (shouldFilterApplicationLocked(
24501                         mSettings.getPackageLPr(component.getPackageName()), callingUid,
24502                         component, TYPE_UNKNOWN, userId)) {
24503                     throw new PackageManager.NameNotFoundException(component.getPackageName());
24504                 }
24505                 return mSettings.getComponentEnabledSettingLPr(component, userId);
24506             } catch (PackageManager.NameNotFoundException e) {
24507                 throw new IllegalArgumentException("Unknown component: " + component);
24508             }
24509         }
24510     }
24511 
24512     /**
24513      * @return true if the runtime app user enabled state, runtime component user enabled state,
24514      * install-time app manifest enabled state, and install-time component manifest enabled state
24515      * are all effectively enabled for the given component. Or if the component cannot be found,
24516      * returns false.
24517      */
24518     private boolean isComponentEffectivelyEnabled(@NonNull ComponentInfo componentInfo,
24519             @UserIdInt int userId) {
24520         synchronized (mLock) {
24521             try {
24522                 String packageName = componentInfo.packageName;
24523                 int appEnabledSetting =
24524                         mSettings.getApplicationEnabledSettingLPr(packageName, userId);
24525                 if (appEnabledSetting == COMPONENT_ENABLED_STATE_DEFAULT) {
24526                     if (!componentInfo.applicationInfo.enabled) {
24527                         return false;
24528                     }
24529                 } else if (appEnabledSetting != COMPONENT_ENABLED_STATE_ENABLED) {
24530                     return false;
24531                 }
24532 
24533                 int componentEnabledSetting = mSettings.getComponentEnabledSettingLPr(
24534                                 componentInfo.getComponentName(), userId);
24535                 if (componentEnabledSetting == COMPONENT_ENABLED_STATE_DEFAULT) {
24536                     return componentInfo.isEnabled();
24537                 } else if (componentEnabledSetting != COMPONENT_ENABLED_STATE_ENABLED) {
24538                     return false;
24539                 }
24540 
24541                 return true;
24542             } catch (PackageManager.NameNotFoundException ignored) {
24543                 return false;
24544             }
24545         }
24546     }
24547 
24548     @Override
24549     public void enterSafeMode() {
24550         enforceSystemOrRoot("Only the system can request entering safe mode");
24551 
24552         if (!mSystemReady) {
24553             mSafeMode = true;
24554         }
24555     }
24556 
24557     @Override
24558     public void systemReady() {
24559         enforceSystemOrRoot("Only the system can claim the system is ready");
24560 
24561         final ContentResolver resolver = mContext.getContentResolver();
24562         if (mReleaseOnSystemReady != null) {
24563             for (int i = mReleaseOnSystemReady.size() - 1; i >= 0; --i) {
24564                 final File dstCodePath = mReleaseOnSystemReady.get(i);
24565                 F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
24566             }
24567             mReleaseOnSystemReady = null;
24568         }
24569         mSystemReady = true;
24570         ContentObserver co = new ContentObserver(mHandler) {
24571             @Override
24572             public void onChange(boolean selfChange) {
24573                 final boolean ephemeralFeatureDisabled =
24574                         Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0;
24575                 for (int userId : UserManagerService.getInstance().getUserIds()) {
24576                     final boolean instantAppsDisabledForUser =
24577                             ephemeralFeatureDisabled || Secure.getIntForUser(resolver,
24578                                     Secure.INSTANT_APPS_ENABLED, 1, userId) == 0;
24579                     mWebInstantAppsDisabled.put(userId, instantAppsDisabledForUser);
24580                 }
24581             }
24582         };
24583         mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
24584                         .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
24585                 false, co, UserHandle.USER_ALL);
24586         mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
24587                         .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
24588         co.onChange(true);
24589 
24590         mAppsFilter.onSystemReady();
24591 
24592         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
24593         // disabled after already being started.
24594         CarrierAppUtils.disableCarrierAppsUntilPrivileged(
24595                 mContext.getOpPackageName(), UserHandle.USER_SYSTEM, mContext);
24596 
24597         disableSkuSpecificApps();
24598 
24599         // Read the compatibilty setting when the system is ready.
24600         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
24601                 mContext.getContentResolver(),
24602                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
24603         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
24604 
24605         if (DEBUG_SETTINGS) {
24606             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
24607         }
24608 
24609         synchronized (mLock) {
24610             ArrayList<Integer> changed = mSettings.systemReady(mComponentResolver);
24611             for (int i = 0; i < changed.size(); i++) {
24612                 mSettings.writePackageRestrictionsLPr(changed.get(i));
24613             }
24614         }
24615 
24616         mUserManager.systemReady();
24617 
24618         // Watch for external volumes that come and go over time
24619         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
24620         storage.registerListener(mStorageListener);
24621 
24622         mInstallerService.systemReady();
24623         mPackageDexOptimizer.systemReady();
24624 
24625         // Now that we're mostly running, clean up stale users and apps
24626         mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
24627         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
24628 
24629         mPermissionManager.onSystemReady();
24630 
24631         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
24632         final List<UserInfo> livingUsers = mInjector.getUserManagerInternal().getUsers(
24633                 /* excludePartial= */ true,
24634                 /* excludeDying= */ true,
24635                 /* excludePreCreated= */ false);
24636         final int livingUserCount = livingUsers.size();
24637         for (int i = 0; i < livingUserCount; i++) {
24638             final int userId = livingUsers.get(i).id;
24639             if (mPmInternal.isPermissionUpgradeNeeded(userId)) {
24640                 grantPermissionsUserIds = ArrayUtils.appendInt(
24641                         grantPermissionsUserIds, userId);
24642             }
24643         }
24644         // If we upgraded grant all default permissions before kicking off.
24645         for (int userId : grantPermissionsUserIds) {
24646             mLegacyPermissionManager.grantDefaultPermissions(userId);
24647         }
24648         if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
24649             // If we did not grant default permissions, we preload from this the
24650             // default permission exceptions lazily to ensure we don't hit the
24651             // disk on a new user creation.
24652             mLegacyPermissionManager.scheduleReadDefaultPermissionExceptions();
24653         }
24654 
24655         if (mInstantAppResolverConnection != null) {
24656             mContext.registerReceiver(new BroadcastReceiver() {
24657                 @Override
24658                 public void onReceive(Context context, Intent intent) {
24659                     mInstantAppResolverConnection.optimisticBind();
24660                     mContext.unregisterReceiver(this);
24661                 }
24662             }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
24663         }
24664 
24665         IntentFilter overlayFilter = new IntentFilter(Intent.ACTION_OVERLAY_CHANGED);
24666         overlayFilter.addDataScheme("package");
24667         mContext.registerReceiver(new BroadcastReceiver() {
24668             @Override
24669             public void onReceive(Context context, Intent intent) {
24670                 if (intent == null) {
24671                     return;
24672                 }
24673                 Uri data = intent.getData();
24674                 if (data == null) {
24675                     return;
24676                 }
24677                 String packageName = data.getSchemeSpecificPart();
24678                 if (packageName == null) {
24679                     return;
24680                 }
24681                 AndroidPackage pkg = mPackages.get(packageName);
24682                 if (pkg == null) {
24683                     return;
24684                 }
24685                 sendPackageChangedBroadcast(pkg.getPackageName(),
24686                         true /* dontKillApp */,
24687                         new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
24688                         pkg.getUid(),
24689                         Intent.ACTION_OVERLAY_CHANGED);
24690             }
24691         }, overlayFilter);
24692 
24693         mModuleInfoProvider.systemReady();
24694 
24695         // Installer service might attempt to install some packages that have been staged for
24696         // installation on reboot. Make sure this is the last component to be call since the
24697         // installation might require other components to be ready.
24698         mInstallerService.restoreAndApplyStagedSessionIfNeeded();
24699 
24700         mExistingPackages = null;
24701 
24702         // Clear cache on flags changes.
24703         DeviceConfig.addOnPropertiesChangedListener(
24704                 NAMESPACE_PACKAGE_MANAGER_SERVICE, mInjector.getBackgroundExecutor(),
24705                 properties -> {
24706                     final Set<String> keyset = properties.getKeyset();
24707                     if (keyset.contains(PROPERTY_INCFS_DEFAULT_TIMEOUTS) || keyset.contains(
24708                             PROPERTY_KNOWN_DIGESTERS_LIST)) {
24709                         mPerUidReadTimeoutsCache = null;
24710                     }
24711                 });
24712     }
24713 
24714     public void waitForAppDataPrepared() {
24715         if (mPrepareAppDataFuture == null) {
24716             return;
24717         }
24718         ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
24719         mPrepareAppDataFuture = null;
24720     }
24721 
24722     @Override
24723     public boolean isSafeMode() {
24724         // allow instant applications
24725         return mSafeMode;
24726     }
24727 
24728     @Override
24729     public boolean hasSystemUidErrors() {
24730         // allow instant applications
24731         return mHasSystemUidErrors;
24732     }
24733 
24734     static String arrayToString(int[] array) {
24735         StringBuilder stringBuilder = new StringBuilder(128);
24736         stringBuilder.append('[');
24737         if (array != null) {
24738             for (int i=0; i<array.length; i++) {
24739                 if (i > 0) stringBuilder.append(", ");
24740                 stringBuilder.append(array[i]);
24741             }
24742         }
24743         stringBuilder.append(']');
24744         return stringBuilder.toString();
24745     }
24746 
24747     @Override
24748     public void onShellCommand(FileDescriptor in, FileDescriptor out,
24749             FileDescriptor err, String[] args, ShellCallback callback,
24750             ResultReceiver resultReceiver) {
24751         (new PackageManagerShellCommand(this, mContext,mDomainVerificationManager.getShell()))
24752                 .exec(this, in, out, err, args, callback, resultReceiver);
24753     }
24754 
24755     @SuppressWarnings("resource")
24756     @Override
24757     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
24758         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
24759 
24760         DumpState dumpState = new DumpState();
24761         ArraySet<String> permissionNames = null;
24762 
24763         int opti = 0;
24764         while (opti < args.length) {
24765             String opt = args[opti];
24766             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
24767                 break;
24768             }
24769             opti++;
24770 
24771             if ("-a".equals(opt)) {
24772                 // Right now we only know how to print all.
24773             } else if ("-h".equals(opt)) {
24774                 pw.println("Package manager dump options:");
24775                 pw.println("  [-h] [-f] [--checkin] [--all-components] [cmd] ...");
24776                 pw.println("    --checkin: dump for a checkin");
24777                 pw.println("    -f: print details of intent filters");
24778                 pw.println("    -h: print this help");
24779                 pw.println("    --all-components: include all component names in package dump");
24780                 pw.println("  cmd may be one of:");
24781                 pw.println("    apex: list active APEXes and APEX session state");
24782                 pw.println("    l[ibraries]: list known shared libraries");
24783                 pw.println("    f[eatures]: list device features");
24784                 pw.println("    k[eysets]: print known keysets");
24785                 pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
24786                 pw.println("    perm[issions]: dump permissions");
24787                 pw.println("    permission [name ...]: dump declaration and use of given permission");
24788                 pw.println("    pref[erred]: print preferred package settings");
24789                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
24790                 pw.println("    prov[iders]: dump content providers");
24791                 pw.println("    p[ackages]: dump installed packages");
24792                 pw.println("    q[ueries]: dump app queryability calculations");
24793                 pw.println("    s[hared-users]: dump shared user IDs");
24794                 pw.println("    m[essages]: print collected runtime messages");
24795                 pw.println("    v[erifiers]: print package verifier info");
24796                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
24797                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
24798                 pw.println("    t[imeouts]: print read timeouts for known digesters");
24799                 pw.println("    version: print database version info");
24800                 pw.println("    write: write current settings now");
24801                 pw.println("    installs: details about install sessions");
24802                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
24803                 pw.println("    dexopt: dump dexopt state");
24804                 pw.println("    compiler-stats: dump compiler statistics");
24805                 pw.println("    service-permissions: dump permissions required by services");
24806                 pw.println("    snapshot: dump snapshot statistics");
24807                 pw.println("    known-packages: dump known packages");
24808                 pw.println("    <package.name>: info about given package");
24809                 return;
24810             } else if ("--checkin".equals(opt)) {
24811                 dumpState.setCheckIn(true);
24812             } else if ("--all-components".equals(opt)) {
24813                 dumpState.setOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS);
24814             } else if ("-f".equals(opt)) {
24815                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
24816             } else if ("--proto".equals(opt)) {
24817                 dumpProto(fd);
24818                 return;
24819             } else {
24820                 pw.println("Unknown argument: " + opt + "; use -h for help");
24821             }
24822         }
24823 
24824         // Is the caller requesting to dump a particular piece of data?
24825         if (opti < args.length) {
24826             String cmd = args[opti];
24827             opti++;
24828             // Is this a package name?
24829             if ("android".equals(cmd) || cmd.contains(".")) {
24830                 dumpState.setTargetPackageName(cmd);
24831                 // When dumping a single package, we always dump all of its
24832                 // filter information since the amount of data will be reasonable.
24833                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
24834             } else if ("check-permission".equals(cmd)) {
24835                 if (opti >= args.length) {
24836                     pw.println("Error: check-permission missing permission argument");
24837                     return;
24838                 }
24839                 String perm = args[opti];
24840                 opti++;
24841                 if (opti >= args.length) {
24842                     pw.println("Error: check-permission missing package argument");
24843                     return;
24844                 }
24845 
24846                 String pkg = args[opti];
24847                 opti++;
24848                 int user = UserHandle.getUserId(Binder.getCallingUid());
24849                 if (opti < args.length) {
24850                     try {
24851                         user = Integer.parseInt(args[opti]);
24852                     } catch (NumberFormatException e) {
24853                         pw.println("Error: check-permission user argument is not a number: "
24854                                 + args[opti]);
24855                         return;
24856                     }
24857                 }
24858 
24859                 // Normalize package name to handle renamed packages and static libs
24860                 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
24861 
24862                 pw.println(checkPermission(perm, pkg, user));
24863                 return;
24864             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
24865                 dumpState.setDump(DumpState.DUMP_LIBS);
24866             } else if ("f".equals(cmd) || "features".equals(cmd)) {
24867                 dumpState.setDump(DumpState.DUMP_FEATURES);
24868             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
24869                 if (opti >= args.length) {
24870                     dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
24871                             | DumpState.DUMP_SERVICE_RESOLVERS
24872                             | DumpState.DUMP_RECEIVER_RESOLVERS
24873                             | DumpState.DUMP_CONTENT_RESOLVERS);
24874                 } else {
24875                     while (opti < args.length) {
24876                         String name = args[opti];
24877                         if ("a".equals(name) || "activity".equals(name)) {
24878                             dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
24879                         } else if ("s".equals(name) || "service".equals(name)) {
24880                             dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
24881                         } else if ("r".equals(name) || "receiver".equals(name)) {
24882                             dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
24883                         } else if ("c".equals(name) || "content".equals(name)) {
24884                             dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
24885                         } else {
24886                             pw.println("Error: unknown resolver table type: " + name);
24887                             return;
24888                         }
24889                         opti++;
24890                     }
24891                 }
24892             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
24893                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
24894             } else if ("permission".equals(cmd)) {
24895                 if (opti >= args.length) {
24896                     pw.println("Error: permission requires permission name");
24897                     return;
24898                 }
24899                 permissionNames = new ArraySet<>();
24900                 while (opti < args.length) {
24901                     permissionNames.add(args[opti]);
24902                     opti++;
24903                 }
24904                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
24905                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
24906             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
24907                 dumpState.setDump(DumpState.DUMP_PREFERRED);
24908             } else if ("preferred-xml".equals(cmd)) {
24909                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
24910                 if (opti < args.length && "--full".equals(args[opti])) {
24911                     dumpState.setFullPreferred(true);
24912                     opti++;
24913                 }
24914             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
24915                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
24916             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
24917                 dumpState.setDump(DumpState.DUMP_PACKAGES);
24918             } else if ("q".equals(cmd) || "queries".equals(cmd)) {
24919                 dumpState.setDump(DumpState.DUMP_QUERIES);
24920             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
24921                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
24922                 if (opti < args.length && "noperm".equals(args[opti])) {
24923                     dumpState.setOptionEnabled(DumpState.OPTION_SKIP_PERMISSIONS);
24924                 }
24925             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
24926                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
24927             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
24928                 dumpState.setDump(DumpState.DUMP_MESSAGES);
24929             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
24930                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
24931             } else if ("dv".equals(cmd) || "domain-verifier".equals(cmd)) {
24932                 dumpState.setDump(DumpState.DUMP_DOMAIN_VERIFIER);
24933             } else if ("version".equals(cmd)) {
24934                 dumpState.setDump(DumpState.DUMP_VERSION);
24935             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
24936                 dumpState.setDump(DumpState.DUMP_KEYSETS);
24937             } else if ("installs".equals(cmd)) {
24938                 dumpState.setDump(DumpState.DUMP_INSTALLS);
24939             } else if ("frozen".equals(cmd)) {
24940                 dumpState.setDump(DumpState.DUMP_FROZEN);
24941             } else if ("volumes".equals(cmd)) {
24942                 dumpState.setDump(DumpState.DUMP_VOLUMES);
24943             } else if ("dexopt".equals(cmd)) {
24944                 dumpState.setDump(DumpState.DUMP_DEXOPT);
24945             } else if ("compiler-stats".equals(cmd)) {
24946                 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
24947             } else if ("changes".equals(cmd)) {
24948                 dumpState.setDump(DumpState.DUMP_CHANGES);
24949             } else if ("service-permissions".equals(cmd)) {
24950                 dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
24951             } else if ("known-packages".equals(cmd)) {
24952                 dumpState.setDump(DumpState.DUMP_KNOWN_PACKAGES);
24953             } else if ("t".equals(cmd) || "timeouts".equals(cmd)) {
24954                 dumpState.setDump(DumpState.DUMP_PER_UID_READ_TIMEOUTS);
24955             } else if ("snapshot".equals(cmd)) {
24956                 dumpState.setDump(DumpState.DUMP_SNAPSHOT_STATISTICS);
24957                 if (opti < args.length) {
24958                     if ("--full".equals(args[opti])) {
24959                         dumpState.setBrief(false);
24960                         opti++;
24961                     } else if ("--brief".equals(args[opti])) {
24962                         dumpState.setBrief(true);
24963                         opti++;
24964                     }
24965                 }
24966             } else if ("write".equals(cmd)) {
24967                 synchronized (mLock) {
24968                     writeSettingsLPrTEMP();
24969                     pw.println("Settings written.");
24970                     return;
24971                 }
24972             }
24973         }
24974 
24975         final String packageName = dumpState.getTargetPackageName();
24976         final boolean checkin = dumpState.isCheckIn();
24977         if (checkin) {
24978             pw.println("vers,1");
24979         }
24980 
24981         // reader
24982         if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
24983             if (!checkin) {
24984                 dump(DumpState.DUMP_VERSION, fd, pw, dumpState);
24985             }
24986         }
24987 
24988         if (!checkin
24989                 && dumpState.isDumping(DumpState.DUMP_KNOWN_PACKAGES)
24990                 && packageName == null) {
24991             if (dumpState.onTitlePrinted()) {
24992                 pw.println();
24993             }
24994             final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
24995             ipw.println("Known Packages:");
24996             ipw.increaseIndent();
24997             for (int i = 0; i <= LAST_KNOWN_PACKAGE; i++) {
24998                 final String knownPackage = mPmInternal.knownPackageToString(i);
24999                 ipw.print(knownPackage);
25000                 ipw.println(":");
25001                 final String[] pkgNames = mPmInternal.getKnownPackageNames(i,
25002                         UserHandle.USER_SYSTEM);
25003                 ipw.increaseIndent();
25004                 if (ArrayUtils.isEmpty(pkgNames)) {
25005                     ipw.println("none");
25006                 } else {
25007                     for (String name : pkgNames) {
25008                         ipw.println(name);
25009                     }
25010                 }
25011                 ipw.decreaseIndent();
25012             }
25013             ipw.decreaseIndent();
25014         }
25015 
25016         if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
25017             final String requiredVerifierPackage = mRequiredVerifierPackage;
25018             if (!checkin) {
25019                 if (dumpState.onTitlePrinted()) {
25020                     pw.println();
25021                 }
25022                 pw.println("Verifiers:");
25023                 pw.print("  Required: ");
25024                 pw.print(requiredVerifierPackage);
25025                 pw.print(" (uid=");
25026                 pw.print(getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
25027                         UserHandle.USER_SYSTEM));
25028                 pw.println(")");
25029             } else if (requiredVerifierPackage != null) {
25030                 pw.print("vrfy,"); pw.print(requiredVerifierPackage);
25031                 pw.print(",");
25032                 pw.println(getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
25033                         UserHandle.USER_SYSTEM));
25034             }
25035         }
25036 
25037         if (dumpState.isDumping(DumpState.DUMP_DOMAIN_VERIFIER) && packageName == null) {
25038             final DomainVerificationProxy proxy = mDomainVerificationManager.getProxy();
25039             final ComponentName verifierComponent = proxy.getComponentName();
25040             if (verifierComponent != null) {
25041                 String verifierPackageName = verifierComponent.getPackageName();
25042                 if (!checkin) {
25043                     if (dumpState.onTitlePrinted())
25044                         pw.println();
25045                     pw.println("Domain Verifier:");
25046                     pw.print("  Using: ");
25047                     pw.print(verifierPackageName);
25048                     pw.print(" (uid=");
25049                     pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
25050                             UserHandle.USER_SYSTEM));
25051                     pw.println(")");
25052                 } else if (verifierPackageName != null) {
25053                     pw.print("dv,"); pw.print(verifierPackageName);
25054                     pw.print(",");
25055                     pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
25056                             UserHandle.USER_SYSTEM));
25057                 }
25058             } else {
25059                 pw.println();
25060                 pw.println("No Domain Verifier available!");
25061             }
25062         }
25063 
25064         if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
25065             dump(DumpState.DUMP_LIBS, fd, pw, dumpState);
25066         }
25067 
25068         if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
25069             if (dumpState.onTitlePrinted()) {
25070                 pw.println();
25071             }
25072             if (!checkin) {
25073                 pw.println("Features:");
25074             }
25075 
25076             synchronized (mAvailableFeatures) {
25077                 for (FeatureInfo feat : mAvailableFeatures.values()) {
25078                     if (checkin) {
25079                         pw.print("feat,");
25080                         pw.print(feat.name);
25081                         pw.print(",");
25082                         pw.println(feat.version);
25083                     } else {
25084                         pw.print("  ");
25085                         pw.print(feat.name);
25086                         if (feat.version > 0) {
25087                             pw.print(" version=");
25088                             pw.print(feat.version);
25089                         }
25090                         pw.println();
25091                     }
25092                 }
25093             }
25094         }
25095 
25096         if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
25097             synchronized (mLock) {
25098                 mComponentResolver.dumpActivityResolvers(pw, dumpState, packageName);
25099             }
25100         }
25101         if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
25102             synchronized (mLock) {
25103                 mComponentResolver.dumpReceiverResolvers(pw, dumpState, packageName);
25104             }
25105         }
25106         if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
25107             synchronized (mLock) {
25108                 mComponentResolver.dumpServiceResolvers(pw, dumpState, packageName);
25109             }
25110         }
25111         if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
25112             synchronized (mLock) {
25113                 mComponentResolver.dumpProviderResolvers(pw, dumpState, packageName);
25114             }
25115         }
25116 
25117         if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
25118             dump(DumpState.DUMP_PREFERRED, fd, pw, dumpState);
25119         }
25120 
25121         if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
25122             dump(DumpState.DUMP_PREFERRED_XML, fd, pw, dumpState);
25123         }
25124 
25125         if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) {
25126             dump(DumpState.DUMP_DOMAIN_PREFERRED, fd, pw, dumpState);
25127         }
25128 
25129         if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
25130             mSettings.dumpPermissions(pw, packageName, permissionNames, dumpState);
25131         }
25132 
25133         if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
25134             synchronized (mLock) {
25135                 mComponentResolver.dumpContentProviders(pw, dumpState, packageName);
25136             }
25137         }
25138 
25139         if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
25140             synchronized (mLock) {
25141                 mSettings.getKeySetManagerService().dumpLPr(pw, packageName, dumpState);
25142             }
25143         }
25144 
25145         if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
25146             // This cannot be moved to ComputerEngine since some variables of the collections
25147             // in PackageUserState such as suspendParams, disabledComponents and enabledComponents
25148             // do not have a copy.
25149             synchronized (mLock) {
25150                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
25151             }
25152         }
25153 
25154         if (dumpState.isDumping(DumpState.DUMP_QUERIES)) {
25155             dump(DumpState.DUMP_QUERIES, fd, pw, dumpState);
25156         }
25157 
25158         if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
25159             // This cannot be moved to ComputerEngine since the set of packages in the
25160             // SharedUserSetting do not have a copy.
25161             synchronized (mLock) {
25162                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
25163             }
25164         }
25165 
25166         if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
25167             if (dumpState.onTitlePrinted()) pw.println();
25168             pw.println("Package Changes:");
25169             synchronized (mLock) {
25170                 pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
25171                 final int K = mChangedPackages.size();
25172                 for (int i = 0; i < K; i++) {
25173                     final SparseArray<String> changes = mChangedPackages.valueAt(i);
25174                     pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
25175                     final int N = changes.size();
25176                     if (N == 0) {
25177                         pw.print("    "); pw.println("No packages changed");
25178                     } else {
25179                         for (int j = 0; j < N; j++) {
25180                             final String pkgName = changes.valueAt(j);
25181                             final int sequenceNumber = changes.keyAt(j);
25182                             pw.print("    ");
25183                             pw.print("seq=");
25184                             pw.print(sequenceNumber);
25185                             pw.print(", package=");
25186                             pw.println(pkgName);
25187                         }
25188                     }
25189                 }
25190             }
25191         }
25192 
25193         if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
25194             // XXX should handle packageName != null by dumping only install data that
25195             // the given package is involved with.
25196             if (dumpState.onTitlePrinted()) pw.println();
25197 
25198             final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
25199             ipw.println();
25200             ipw.println("Frozen packages:");
25201             ipw.increaseIndent();
25202             synchronized (mLock) {
25203                 if (mFrozenPackages.size() == 0) {
25204                     ipw.println("(none)");
25205                 } else {
25206                     for (int i = 0; i < mFrozenPackages.size(); i++) {
25207                         ipw.println(mFrozenPackages.valueAt(i));
25208                     }
25209                 }
25210             }
25211             ipw.decreaseIndent();
25212         }
25213 
25214         if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
25215             if (dumpState.onTitlePrinted()) pw.println();
25216 
25217             final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
25218             ipw.println();
25219             ipw.println("Loaded volumes:");
25220             ipw.increaseIndent();
25221             synchronized (mLoadedVolumes) {
25222                 if (mLoadedVolumes.size() == 0) {
25223                     ipw.println("(none)");
25224                 } else {
25225                     for (int i = 0; i < mLoadedVolumes.size(); i++) {
25226                         ipw.println(mLoadedVolumes.valueAt(i));
25227                     }
25228                 }
25229             }
25230             ipw.decreaseIndent();
25231         }
25232 
25233         if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
25234                 && packageName == null) {
25235             synchronized (mLock) {
25236                 mComponentResolver.dumpServicePermissions(pw, dumpState);
25237             }
25238         }
25239 
25240         if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
25241             if (dumpState.onTitlePrinted()) pw.println();
25242             dump(DumpState.DUMP_DEXOPT, fd, pw, dumpState);
25243         }
25244 
25245         if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
25246             if (dumpState.onTitlePrinted()) pw.println();
25247             dump(DumpState.DUMP_COMPILER_STATS, fd, pw, dumpState);
25248         }
25249 
25250         if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
25251             if (dumpState.onTitlePrinted()) pw.println();
25252             synchronized (mLock) {
25253                 mSettings.dumpReadMessagesLPr(pw, dumpState);
25254             }
25255             pw.println();
25256             pw.println("Package warning messages:");
25257             dumpCriticalInfo(pw, null);
25258         }
25259 
25260         if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
25261             dumpCriticalInfo(pw, "msg,");
25262         }
25263 
25264         // PackageInstaller should be called outside of mPackages lock
25265         if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
25266             // XXX should handle packageName != null by dumping only install data that
25267             // the given package is involved with.
25268             if (dumpState.onTitlePrinted()) pw.println();
25269             mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
25270         }
25271 
25272         if (!checkin && dumpState.isDumping(DumpState.DUMP_APEX)) {
25273             mApexManager.dump(pw, packageName);
25274         }
25275 
25276         if (!checkin && dumpState.isDumping(DumpState.DUMP_PER_UID_READ_TIMEOUTS)
25277                 && packageName == null) {
25278             pw.println();
25279             pw.println("Per UID read timeouts:");
25280             pw.println("    Default timeouts flag: " + getDefaultTimeouts());
25281             pw.println("    Known digesters list flag: " + getKnownDigestersList());
25282 
25283             PerUidReadTimeouts[] items = getPerUidReadTimeouts();
25284             pw.println("    Timeouts (" + items.length + "):");
25285             for (PerUidReadTimeouts item : items) {
25286                 pw.print("        (");
25287                 pw.print("uid=" + item.uid + ", ");
25288                 pw.print("minTimeUs=" + item.minTimeUs + ", ");
25289                 pw.print("minPendingTimeUs=" + item.minPendingTimeUs + ", ");
25290                 pw.print("maxPendingTimeUs=" + item.maxPendingTimeUs);
25291                 pw.println(")");
25292             }
25293         }
25294 
25295         if (!checkin && dumpState.isDumping(DumpState.DUMP_SNAPSHOT_STATISTICS)) {
25296             pw.println("Snapshot statistics");
25297             if (!mSnapshotEnabled) {
25298                 pw.println("  Snapshots disabled");
25299             } else {
25300                 int hits = 0;
25301                 int level = sSnapshotCorked.get();
25302                 synchronized (mSnapshotLock) {
25303                     if (mSnapshotComputer != null) {
25304                         hits = mSnapshotComputer.getUsed();
25305                     }
25306                 }
25307                 final long now = SystemClock.currentTimeMicro();
25308                 mSnapshotStatistics.dump(pw, "  ", now, hits, level, dumpState.isBrief());
25309             }
25310         }
25311     }
25312 
25313     /**
25314      * Dump package manager states to the file according to a given dumping type of
25315      * {@link DumpState}.
25316      */
25317     private void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
25318         mComputer.dump(type, fd, pw, dumpState);
25319     }
25320 
25321     //TODO: b/111402650
25322     private void disableSkuSpecificApps() {
25323         String apkList[] = mContext.getResources().getStringArray(
25324                 R.array.config_disableApksUnlessMatchedSku_apk_list);
25325         String skuArray[] = mContext.getResources().getStringArray(
25326                 R.array.config_disableApkUnlessMatchedSku_skus_list);
25327         if (ArrayUtils.isEmpty(apkList)) {
25328            return;
25329         }
25330         String sku = SystemProperties.get("ro.boot.hardware.sku");
25331         if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
25332             return;
25333         }
25334         for (String packageName : apkList) {
25335             setSystemAppHiddenUntilInstalled(packageName, true);
25336             for (UserInfo user : mInjector.getUserManagerInternal().getUsers(false)) {
25337                 setSystemAppInstallState(packageName, false, user.id);
25338             }
25339         }
25340     }
25341 
25342     private void dumpProto(FileDescriptor fd) {
25343         final ProtoOutputStream proto = new ProtoOutputStream(fd);
25344 
25345         synchronized (mLock) {
25346             final long requiredVerifierPackageToken =
25347                     proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
25348             proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
25349             proto.write(
25350                     PackageServiceDumpProto.PackageShortProto.UID,
25351                     getPackageUid(
25352                             mRequiredVerifierPackage,
25353                             MATCH_DEBUG_TRIAGED_MISSING,
25354                             UserHandle.USER_SYSTEM));
25355             proto.end(requiredVerifierPackageToken);
25356 
25357             DomainVerificationProxy proxy = mDomainVerificationManager.getProxy();
25358             ComponentName verifierComponent = proxy.getComponentName();
25359             if (verifierComponent != null) {
25360                 String verifierPackageName = verifierComponent.getPackageName();
25361                 final long verifierPackageToken =
25362                         proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
25363                 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
25364                 proto.write(
25365                         PackageServiceDumpProto.PackageShortProto.UID,
25366                         getPackageUid(
25367                                 verifierPackageName,
25368                                 MATCH_DEBUG_TRIAGED_MISSING,
25369                                 UserHandle.USER_SYSTEM));
25370                 proto.end(verifierPackageToken);
25371             }
25372 
25373             dumpSharedLibrariesProto(proto);
25374             dumpFeaturesProto(proto);
25375             mSettings.dumpPackagesProto(proto);
25376             mSettings.dumpSharedUsersProto(proto);
25377             dumpCriticalInfo(proto);
25378         }
25379         proto.flush();
25380     }
25381 
25382     private void dumpFeaturesProto(ProtoOutputStream proto) {
25383         synchronized (mAvailableFeatures) {
25384             final int count = mAvailableFeatures.size();
25385             for (int i = 0; i < count; i++) {
25386                 mAvailableFeatures.valueAt(i).dumpDebug(proto, PackageServiceDumpProto.FEATURES);
25387             }
25388         }
25389     }
25390 
25391     private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
25392         final int count = mSharedLibraries.size();
25393         for (int i = 0; i < count; i++) {
25394             final String libName = mSharedLibraries.keyAt(i);
25395             WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
25396             if (versionedLib == null) {
25397                 continue;
25398             }
25399             final int versionCount = versionedLib.size();
25400             for (int j = 0; j < versionCount; j++) {
25401                 final SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
25402                 final long sharedLibraryToken =
25403                         proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
25404                 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libraryInfo.getName());
25405                 final boolean isJar = (libraryInfo.getPath() != null);
25406                 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
25407                 if (isJar) {
25408                     proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH,
25409                             libraryInfo.getPath());
25410                 } else {
25411                     proto.write(PackageServiceDumpProto.SharedLibraryProto.APK,
25412                             libraryInfo.getPackageName());
25413                 }
25414                 proto.end(sharedLibraryToken);
25415             }
25416         }
25417     }
25418 
25419     // ------- apps on sdcard specific code -------
25420     static final boolean DEBUG_SD_INSTALL = false;
25421 
25422     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
25423 
25424     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
25425 
25426     private boolean mMediaMounted = false;
25427 
25428     static String getEncryptKey() {
25429         try {
25430             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
25431                     SD_ENCRYPTION_KEYSTORE_NAME);
25432             if (sdEncKey == null) {
25433                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
25434                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
25435                 if (sdEncKey == null) {
25436                     Slog.e(TAG, "Failed to create encryption keys");
25437                     return null;
25438                 }
25439             }
25440             return sdEncKey;
25441         } catch (NoSuchAlgorithmException nsae) {
25442             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
25443             return null;
25444         } catch (IOException ioe) {
25445             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
25446             return null;
25447         }
25448     }
25449 
25450     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
25451             ArrayList<AndroidPackage> packages, IIntentReceiver finishedReceiver) {
25452         final int size = packages.size();
25453         final String[] packageNames = new String[size];
25454         final int[] packageUids = new int[size];
25455         for (int i = 0; i < size; i++) {
25456             final AndroidPackage pkg = packages.get(i);
25457             packageNames[i] = pkg.getPackageName();
25458             packageUids[i] = pkg.getUid();
25459         }
25460         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
25461                 finishedReceiver);
25462     }
25463 
25464     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
25465             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
25466         sendResourcesChangedBroadcast(mediaStatus, replacing,
25467                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
25468     }
25469 
25470     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
25471             String[] pkgList, int[] uidArr, IIntentReceiver finishedReceiver) {
25472         int size = pkgList.length;
25473         if (size > 0) {
25474             // Send broadcasts here
25475             Bundle extras = new Bundle();
25476             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
25477             if (uidArr != null) {
25478                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
25479             }
25480             if (replacing) {
25481                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
25482             }
25483             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
25484                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
25485             // TODO: not sure how to handle this one.
25486             sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver,
25487                     null, null, null, null);
25488         }
25489     }
25490 
25491     private void loadPrivatePackages(final VolumeInfo vol) {
25492         mHandler.post(() -> loadPrivatePackagesInner(vol));
25493     }
25494 
25495     private void loadPrivatePackagesInner(VolumeInfo vol) {
25496         final String volumeUuid = vol.fsUuid;
25497         if (TextUtils.isEmpty(volumeUuid)) {
25498             Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
25499             return;
25500         }
25501 
25502         final ArrayList<PackageFreezer> freezers = new ArrayList<>();
25503         final ArrayList<AndroidPackage> loaded = new ArrayList<>();
25504         final int parseFlags = mDefParseFlags | ParsingPackageUtils.PARSE_EXTERNAL_STORAGE;
25505 
25506         final VersionInfo ver;
25507         final List<PackageSetting> packages;
25508         synchronized (mLock) {
25509             ver = mSettings.findOrCreateVersion(volumeUuid);
25510             packages = mSettings.getVolumePackagesLPr(volumeUuid);
25511         }
25512 
25513         for (PackageSetting ps : packages) {
25514             freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
25515             synchronized (mInstallLock) {
25516                 final AndroidPackage pkg;
25517                 try {
25518                     pkg = scanPackageTracedLI(ps.getPath(), parseFlags, SCAN_INITIAL, 0, null);
25519                     loaded.add(pkg);
25520 
25521                 } catch (PackageManagerException e) {
25522                     Slog.w(TAG, "Failed to scan " + ps.getPath() + ": " + e.getMessage());
25523                 }
25524 
25525                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
25526                     clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
25527                             | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
25528                             | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
25529                 }
25530             }
25531         }
25532 
25533         // Reconcile app data for all started/unlocked users
25534         final StorageManager sm = mInjector.getSystemService(StorageManager.class);
25535         UserManagerInternal umInternal = mInjector.getUserManagerInternal();
25536         StorageManagerInternal smInternal = mInjector.getLocalService(StorageManagerInternal.class);
25537         for (UserInfo user : mUserManager.getUsers(false /* includeDying */)) {
25538             final int flags;
25539             if (StorageManager.isUserKeyUnlocked(user.id)
25540                     && smInternal.isCeStoragePrepared(user.id)) {
25541                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
25542             } else if (umInternal.isUserRunning(user.id)) {
25543                 flags = StorageManager.FLAG_STORAGE_DE;
25544             } else {
25545                 continue;
25546             }
25547 
25548             try {
25549                 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
25550                 synchronized (mInstallLock) {
25551                     reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
25552                 }
25553             } catch (IllegalStateException e) {
25554                 // Device was probably ejected, and we'll process that event momentarily
25555                 Slog.w(TAG, "Failed to prepare storage: " + e);
25556             }
25557         }
25558 
25559         synchronized (mLock) {
25560             final boolean isUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
25561             if (isUpgrade) {
25562                 logCriticalInfo(Log.INFO, "Build fingerprint changed from " + ver.fingerprint
25563                         + " to " + Build.FINGERPRINT + "; regranting permissions for "
25564                         + volumeUuid);
25565             }
25566             mPermissionManager.onStorageVolumeMounted(volumeUuid, isUpgrade);
25567 
25568             // Yay, everything is now upgraded
25569             ver.forceCurrent();
25570 
25571             writeSettingsLPrTEMP();
25572         }
25573 
25574         for (PackageFreezer freezer : freezers) {
25575             freezer.close();
25576         }
25577 
25578         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
25579         sendResourcesChangedBroadcast(true, false, loaded, null);
25580         synchronized (mLoadedVolumes) {
25581             mLoadedVolumes.add(vol.getId());
25582         }
25583     }
25584 
25585     private void unloadPrivatePackages(final VolumeInfo vol) {
25586         mHandler.post(() -> unloadPrivatePackagesInner(vol));
25587     }
25588 
25589     private void unloadPrivatePackagesInner(VolumeInfo vol) {
25590         final String volumeUuid = vol.fsUuid;
25591         if (TextUtils.isEmpty(volumeUuid)) {
25592             Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
25593             return;
25594         }
25595 
25596         final int[] userIds = mUserManager.getUserIds();
25597         final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
25598         synchronized (mInstallLock) {
25599             synchronized (mLock) {
25600                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
25601                 for (PackageSetting ps : packages) {
25602                     if (ps.pkg == null) continue;
25603 
25604                     final AndroidPackage pkg = ps.pkg;
25605                     final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
25606                     final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
25607 
25608                     try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
25609                             "unloadPrivatePackagesInner")) {
25610                         if (deletePackageLIF(ps.name, null, false, userIds, deleteFlags, outInfo,
25611                                 false, null)) {
25612                             unloaded.add(pkg);
25613                         } else {
25614                             Slog.w(TAG, "Failed to unload " + ps.getPath());
25615                         }
25616                     }
25617 
25618                     // Try very hard to release any references to this package
25619                     // so we don't risk the system server being killed due to
25620                     // open FDs
25621                     AttributeCache.instance().removePackage(ps.name);
25622                 }
25623 
25624                 writeSettingsLPrTEMP();
25625             }
25626         }
25627 
25628         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
25629         sendResourcesChangedBroadcast(false, false, unloaded, null);
25630         synchronized (mLoadedVolumes) {
25631             mLoadedVolumes.remove(vol.getId());
25632         }
25633 
25634         // Try very hard to release any references to this path so we don't risk
25635         // the system server being killed due to open FDs
25636         ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
25637 
25638         for (int i = 0; i < 3; i++) {
25639             System.gc();
25640             System.runFinalization();
25641         }
25642     }
25643 
25644     private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
25645             throws PackageManagerException {
25646         synchronized (mLock) {
25647             // Normalize package name to handle renamed packages
25648             packageName = normalizePackageNameLPr(packageName);
25649 
25650             final PackageSetting ps = mSettings.getPackageLPr(packageName);
25651             if (ps == null) {
25652                 throw new PackageManagerException("Package " + packageName + " is unknown");
25653             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
25654                 throw new PackageManagerException(
25655                         "Package " + packageName + " found on unknown volume " + volumeUuid
25656                                 + "; expected volume " + ps.volumeUuid);
25657             } else if (!ps.getInstalled(userId)) {
25658                 throw new PackageManagerException(
25659                         "Package " + packageName + " not installed for user " + userId);
25660             }
25661         }
25662     }
25663 
25664     private List<String> collectAbsoluteCodePaths() {
25665         synchronized (mLock) {
25666             List<String> codePaths = new ArrayList<>();
25667             final int packageCount = mSettings.getPackagesLocked().size();
25668             for (int i = 0; i < packageCount; i++) {
25669                 final PackageSetting ps = mSettings.getPackagesLocked().valueAt(i);
25670                 codePaths.add(ps.getPath().getAbsolutePath());
25671             }
25672             return codePaths;
25673         }
25674     }
25675 
25676     private void executeBatchLI(@NonNull Installer.Batch batch) {
25677         try {
25678             batch.execute(mInstaller);
25679         } catch (InstallerException e) {
25680             Slog.w(TAG, "Failed to execute pending operations", e);
25681         }
25682     }
25683 
25684     /**
25685      * Examine all apps present on given mounted volume, and destroy apps that
25686      * aren't expected, either due to uninstallation or reinstallation on
25687      * another volume.
25688      */
25689     private void reconcileApps(String volumeUuid) {
25690         List<String> absoluteCodePaths = collectAbsoluteCodePaths();
25691         List<File> filesToDelete = null;
25692 
25693         final File[] files = FileUtils.listFilesOrEmpty(
25694                 Environment.getDataAppDirectory(volumeUuid));
25695         for (File file : files) {
25696             final boolean isPackage = (isApkFile(file) || file.isDirectory())
25697                     && !PackageInstallerService.isStageName(file.getName());
25698             if (!isPackage) {
25699                 // Ignore entries which are not packages
25700                 continue;
25701             }
25702 
25703             String absolutePath = file.getAbsolutePath();
25704 
25705             boolean pathValid = false;
25706             final int absoluteCodePathCount = absoluteCodePaths.size();
25707             for (int i = 0; i < absoluteCodePathCount; i++) {
25708                 String absoluteCodePath = absoluteCodePaths.get(i);
25709                 if (absoluteCodePath.startsWith(absolutePath)) {
25710                     pathValid = true;
25711                     break;
25712                 }
25713             }
25714 
25715             if (!pathValid) {
25716                 if (filesToDelete == null) {
25717                     filesToDelete = new ArrayList<>();
25718                 }
25719                 filesToDelete.add(file);
25720             }
25721         }
25722 
25723         if (filesToDelete != null) {
25724             final int fileToDeleteCount = filesToDelete.size();
25725             for (int i = 0; i < fileToDeleteCount; i++) {
25726                 File fileToDelete = filesToDelete.get(i);
25727                 logCriticalInfo(Log.WARN, "Destroying orphaned at " + fileToDelete);
25728                 synchronized (mInstallLock) {
25729                     removeCodePathLI(fileToDelete);
25730                 }
25731             }
25732         }
25733     }
25734 
25735     /**
25736      * Reconcile all app data for the given user.
25737      * <p>
25738      * Verifies that directories exist and that ownership and labeling is
25739      * correct for all installed apps on all mounted volumes.
25740      */
25741     void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
25742         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
25743         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
25744             final String volumeUuid = vol.getFsUuid();
25745             synchronized (mInstallLock) {
25746                 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
25747             }
25748         }
25749     }
25750 
25751     @GuardedBy("mInstallLock")
25752     private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
25753             boolean migrateAppData) {
25754         reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
25755     }
25756 
25757     /**
25758      * Reconcile all app data on given mounted volume.
25759      * <p>
25760      * Destroys app data that isn't expected, either due to uninstallation or
25761      * reinstallation on another volume.
25762      * <p>
25763      * Verifies that directories exist and that ownership and labeling is
25764      * correct for all installed apps.
25765      * @return list of skipped non-core packages (if {@code onlyCoreApps} is true)
25766      */
25767     @GuardedBy("mInstallLock")
25768     private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
25769             boolean migrateAppData, boolean onlyCoreApps) {
25770         Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
25771                 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
25772         List<String> result = onlyCoreApps ? new ArrayList<>() : null;
25773 
25774         final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
25775         final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
25776 
25777         // First look for stale data that doesn't belong, and check if things
25778         // have changed since we did our last restorecon
25779         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
25780             if (StorageManager.isFileEncryptedNativeOrEmulated()
25781                     && !StorageManager.isUserKeyUnlocked(userId)) {
25782                 throw new RuntimeException(
25783                         "Yikes, someone asked us to reconcile CE storage while " + userId
25784                                 + " was still locked; this would have caused massive data loss!");
25785             }
25786 
25787             final File[] files = FileUtils.listFilesOrEmpty(ceDir);
25788             for (File file : files) {
25789                 final String packageName = file.getName();
25790                 try {
25791                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
25792                 } catch (PackageManagerException e) {
25793                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
25794                     try {
25795                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
25796                                 StorageManager.FLAG_STORAGE_CE, 0);
25797                     } catch (InstallerException e2) {
25798                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
25799                     }
25800                 }
25801             }
25802         }
25803         if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
25804             final File[] files = FileUtils.listFilesOrEmpty(deDir);
25805             for (File file : files) {
25806                 final String packageName = file.getName();
25807                 try {
25808                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
25809                 } catch (PackageManagerException e) {
25810                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
25811                     try {
25812                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
25813                                 StorageManager.FLAG_STORAGE_DE, 0);
25814                     } catch (InstallerException e2) {
25815                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
25816                     }
25817                 }
25818             }
25819         }
25820 
25821         // Ensure that data directories are ready to roll for all packages
25822         // installed for this volume and user
25823         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "prepareAppDataAndMigrate");
25824         Installer.Batch batch = new Installer.Batch();
25825         final List<PackageSetting> packages;
25826         synchronized (mLock) {
25827             packages = mSettings.getVolumePackagesLPr(volumeUuid);
25828         }
25829         int preparedCount = 0;
25830         for (PackageSetting ps : packages) {
25831             final String packageName = ps.name;
25832             if (ps.pkg == null) {
25833                 Slog.w(TAG, "Odd, missing scanned package " + packageName);
25834                 // TODO: might be due to legacy ASEC apps; we should circle back
25835                 // and reconcile again once they're scanned
25836                 continue;
25837             }
25838             // Skip non-core apps if requested
25839             if (onlyCoreApps && !ps.pkg.isCoreApp()) {
25840                 result.add(packageName);
25841                 continue;
25842             }
25843 
25844             if (ps.getInstalled(userId)) {
25845                 prepareAppDataAndMigrate(batch, ps.pkg, userId, flags, migrateAppData);
25846                 preparedCount++;
25847             }
25848         }
25849         executeBatchLI(batch);
25850         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
25851 
25852         Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
25853         return result;
25854     }
25855 
25856     /**
25857      * Prepare app data for the given app just after it was installed or
25858      * upgraded. This method carefully only touches users that it's installed
25859      * for, and it forces a restorecon to handle any seinfo changes.
25860      * <p>
25861      * Verifies that directories exist and that ownership and labeling is
25862      * correct for all installed apps. If there is an ownership mismatch, it
25863      * will try recovering system apps by wiping data; third-party app data is
25864      * left intact.
25865      * <p>
25866      * <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em>
25867      */
25868     private void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
25869         final PackageSetting ps;
25870         synchronized (mLock) {
25871             ps = mSettings.getPackageLPr(pkg.getPackageName());
25872             mSettings.writeKernelMappingLPr(ps);
25873         }
25874 
25875         Installer.Batch batch = new Installer.Batch();
25876         UserManagerInternal umInternal = mInjector.getUserManagerInternal();
25877         StorageManagerInternal smInternal = mInjector.getLocalService(StorageManagerInternal.class);
25878         for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) {
25879             final int flags;
25880             if (StorageManager.isUserKeyUnlocked(user.id)
25881                     && smInternal.isCeStoragePrepared(user.id)) {
25882                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
25883             } else if (umInternal.isUserRunning(user.id)) {
25884                 flags = StorageManager.FLAG_STORAGE_DE;
25885             } else {
25886                 continue;
25887             }
25888 
25889             if (ps.getInstalled(user.id)) {
25890                 // TODO: when user data is locked, mark that we're still dirty
25891                 prepareAppData(batch, pkg, user.id, flags).thenRun(() -> {
25892                     // Note: this code block is executed with the Installer lock
25893                     // already held, since it's invoked as a side-effect of
25894                     // executeBatchLI()
25895                     if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
25896                         // Prepare app data on external storage; currently this is used to
25897                         // setup any OBB dirs that were created by the installer correctly.
25898                         int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
25899                         smInternal.prepareAppDataAfterInstall(pkg.getPackageName(), uid);
25900                     }
25901                 });
25902             }
25903         }
25904         executeBatchLI(batch);
25905     }
25906 
25907     /**
25908      * Prepare app data for the given app.
25909      * <p>
25910      * Verifies that directories exist and that ownership and labeling is
25911      * correct for all installed apps. If there is an ownership mismatch, this
25912      * will try recovering system apps by wiping data; third-party app data is
25913      * left intact.
25914      */
25915     private @NonNull CompletableFuture<?> prepareAppData(@NonNull Installer.Batch batch,
25916             @Nullable AndroidPackage pkg, int userId, int flags) {
25917         if (pkg == null) {
25918             Slog.wtf(TAG, "Package was null!", new Throwable());
25919             return CompletableFuture.completedFuture(null);
25920         }
25921         return prepareAppDataLeaf(batch, pkg, userId, flags);
25922     }
25923 
25924     private @NonNull CompletableFuture<?> prepareAppDataAndMigrate(@NonNull Installer.Batch batch,
25925             @NonNull AndroidPackage pkg, int userId, int flags, boolean maybeMigrateAppData) {
25926         return prepareAppData(batch, pkg, userId, flags).thenRun(() -> {
25927             // Note: this code block is executed with the Installer lock
25928             // already held, since it's invoked as a side-effect of
25929             // executeBatchLI()
25930             if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
25931                 // We may have just shuffled around app data directories, so
25932                 // prepare them one more time
25933                 final Installer.Batch batchInner = new Installer.Batch();
25934                 prepareAppData(batchInner, pkg, userId, flags);
25935                 executeBatchLI(batchInner);
25936             }
25937         });
25938     }
25939 
25940     private @NonNull CompletableFuture<?> prepareAppDataLeaf(@NonNull Installer.Batch batch,
25941             @NonNull AndroidPackage pkg, int userId, int flags) {
25942         if (DEBUG_APP_DATA) {
25943             Slog.v(TAG, "prepareAppData for " + pkg.getPackageName() + " u" + userId + " 0x"
25944                     + Integer.toHexString(flags));
25945         }
25946 
25947         final PackageSetting ps;
25948         synchronized (mLock) {
25949             ps = mSettings.getPackageLPr(pkg.getPackageName());
25950         }
25951         final String volumeUuid = pkg.getVolumeUuid();
25952         final String packageName = pkg.getPackageName();
25953 
25954         final int appId = UserHandle.getAppId(pkg.getUid());
25955 
25956         String pkgSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
25957 
25958         Preconditions.checkNotNull(pkgSeInfo);
25959 
25960         final String seInfo = pkgSeInfo + (pkg.getSeInfoUser() != null ? pkg.getSeInfoUser() : "");
25961         final int targetSdkVersion = pkg.getTargetSdkVersion();
25962 
25963         return batch.createAppData(volumeUuid, packageName, userId, flags, appId, seInfo,
25964                 targetSdkVersion).whenComplete((ceDataInode, e) -> {
25965                     // Note: this code block is executed with the Installer lock
25966                     // already held, since it's invoked as a side-effect of
25967                     // executeBatchLI()
25968                     if (e != null) {
25969                         logCriticalInfo(Log.WARN, "Failed to create app data for " + packageName
25970                                 + ", but trying to recover: " + e);
25971                         destroyAppDataLeafLIF(pkg, userId, flags);
25972                         try {
25973                             ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId,
25974                                     flags, appId, seInfo, pkg.getTargetSdkVersion());
25975                             logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
25976                         } catch (InstallerException e2) {
25977                             logCriticalInfo(Log.DEBUG, "Recovery failed!");
25978                         }
25979                     } else if (e != null) {
25980                         Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
25981                     }
25982 
25983                     // Prepare the application profiles only for upgrades and
25984                     // first boot (so that we don't repeat the same operation at
25985                     // each boot).
25986                     //
25987                     // We only have to cover the upgrade and first boot here
25988                     // because for app installs we prepare the profiles before
25989                     // invoking dexopt (in installPackageLI).
25990                     //
25991                     // We also have to cover non system users because we do not
25992                     // call the usual install package methods for them.
25993                     //
25994                     // NOTE: in order to speed up first boot time we only create
25995                     // the current profile and do not update the content of the
25996                     // reference profile. A system image should already be
25997                     // configured with the right profile keys and the profiles
25998                     // for the speed-profile prebuilds should already be copied.
25999                     // That's done in #performDexOptUpgrade.
26000                     //
26001                     // TODO(calin, mathieuc): We should use .dm files for
26002                     // prebuilds profiles instead of manually copying them in
26003                     // #performDexOptUpgrade. When we do that we should have a
26004                     // more granular check here and only update the existing
26005                     // profiles.
26006                     if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
26007                         mArtManagerService.prepareAppProfiles(pkg, userId,
26008                             /* updateReferenceProfileContent= */ false);
26009                     }
26010 
26011                     if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
26012                         // TODO: mark this structure as dirty so we persist it!
26013                         synchronized (mLock) {
26014                             if (ps != null) {
26015                                 ps.setCeDataInode(ceDataInode, userId);
26016                             }
26017                         }
26018                     }
26019 
26020                     prepareAppDataContentsLeafLIF(pkg, ps, userId, flags);
26021                 });
26022     }
26023 
26024     private void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting,
26025             int userId, int flags) {
26026         if (pkg == null) {
26027             Slog.wtf(TAG, "Package was null!", new Throwable());
26028             return;
26029         }
26030         prepareAppDataContentsLeafLIF(pkg, pkgSetting, userId, flags);
26031     }
26032 
26033     private void prepareAppDataContentsLeafLIF(AndroidPackage pkg,
26034             @Nullable PackageSetting pkgSetting, int userId, int flags) {
26035         final String volumeUuid = pkg.getVolumeUuid();
26036         final String packageName = pkg.getPackageName();
26037 
26038         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
26039             // Create a native library symlink only if we have native libraries
26040             // and if the native libraries are 32 bit libraries. We do not provide
26041             // this symlink for 64 bit libraries.
26042             String primaryCpuAbi = AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting);
26043             if (primaryCpuAbi != null && !VMRuntime.is64BitAbi(primaryCpuAbi)) {
26044                 final String nativeLibPath = pkg.getNativeLibraryDir();
26045                 try {
26046                     mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
26047                             nativeLibPath, userId);
26048                 } catch (InstallerException e) {
26049                     Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
26050                 }
26051             }
26052         }
26053     }
26054 
26055     /**
26056      * For system apps on non-FBE devices, this method migrates any existing
26057      * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
26058      * requested by the app.
26059      */
26060     private boolean maybeMigrateAppDataLIF(AndroidPackage pkg, int userId) {
26061         if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
26062                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
26063             final int storageTarget = pkg.isDefaultToDeviceProtectedStorage()
26064                     ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
26065             try {
26066                 mInstaller.migrateAppData(pkg.getVolumeUuid(), pkg.getPackageName(), userId,
26067                         storageTarget);
26068             } catch (InstallerException e) {
26069                 logCriticalInfo(Log.WARN,
26070                         "Failed to migrate " + pkg.getPackageName() + ": " + e.getMessage());
26071             }
26072             return true;
26073         } else {
26074             return false;
26075         }
26076     }
26077 
26078     public PackageFreezer freezePackage(String packageName, String killReason) {
26079         return freezePackage(packageName, UserHandle.USER_ALL, killReason);
26080     }
26081 
26082     public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
26083         return new PackageFreezer(packageName, userId, killReason);
26084     }
26085 
26086     public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
26087             String killReason) {
26088         return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
26089     }
26090 
26091     public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
26092             String killReason) {
26093         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
26094             return new PackageFreezer();
26095         } else {
26096             return freezePackage(packageName, userId, killReason);
26097         }
26098     }
26099 
26100     public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
26101             String killReason) {
26102         return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
26103     }
26104 
26105     public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
26106             String killReason) {
26107         if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
26108             return new PackageFreezer();
26109         } else {
26110             return freezePackage(packageName, userId, killReason);
26111         }
26112     }
26113 
26114     /**
26115      * Class that freezes and kills the given package upon creation, and
26116      * unfreezes it upon closing. This is typically used when doing surgery on
26117      * app code/data to prevent the app from running while you're working.
26118      */
26119     private class PackageFreezer implements AutoCloseable {
26120         private final String mPackageName;
26121 
26122         private final boolean mWeFroze;
26123 
26124         private final AtomicBoolean mClosed = new AtomicBoolean();
26125         private final CloseGuard mCloseGuard = CloseGuard.get();
26126 
26127         /**
26128          * Create and return a stub freezer that doesn't actually do anything,
26129          * typically used when someone requested
26130          * {@link PackageManager#INSTALL_DONT_KILL_APP} or
26131          * {@link PackageManager#DELETE_DONT_KILL_APP}.
26132          */
26133         public PackageFreezer() {
26134             mPackageName = null;
26135             mWeFroze = false;
26136             mCloseGuard.open("close");
26137         }
26138 
26139         public PackageFreezer(String packageName, int userId, String killReason) {
26140             synchronized (mLock) {
26141                 mPackageName = packageName;
26142                 mWeFroze = mFrozenPackages.add(mPackageName);
26143 
26144                 final PackageSetting ps = mSettings.getPackageLPr(mPackageName);
26145                 if (ps != null) {
26146                     killApplication(ps.name, ps.appId, userId, killReason);
26147                 }
26148             }
26149             mCloseGuard.open("close");
26150         }
26151 
26152         @Override
26153         protected void finalize() throws Throwable {
26154             try {
26155                 mCloseGuard.warnIfOpen();
26156                 close();
26157             } finally {
26158                 super.finalize();
26159             }
26160         }
26161 
26162         @Override
26163         public void close() {
26164             mCloseGuard.close();
26165             if (mClosed.compareAndSet(false, true)) {
26166                 synchronized (mLock) {
26167                     if (mWeFroze) {
26168                         mFrozenPackages.remove(mPackageName);
26169                     }
26170                 }
26171             }
26172         }
26173     }
26174 
26175     /**
26176      * Verify that given package is currently frozen.
26177      */
26178     private void checkPackageFrozen(String packageName) {
26179         synchronized (mLock) {
26180             if (!mFrozenPackages.contains(packageName)) {
26181                 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
26182             }
26183         }
26184     }
26185 
26186     @Override
26187     public int movePackage(final String packageName, final String volumeUuid) {
26188         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
26189 
26190         final int callingUid = Binder.getCallingUid();
26191         final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
26192         final int moveId = mNextMoveId.getAndIncrement();
26193         mHandler.post(() -> {
26194             try {
26195                 movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
26196             } catch (PackageManagerException e) {
26197                 Slog.w(TAG, "Failed to move " + packageName, e);
26198                 mMoveCallbacks.notifyStatusChanged(moveId, e.error);
26199             }
26200         });
26201         return moveId;
26202     }
26203 
26204     private void movePackageInternal(final String packageName, final String volumeUuid,
26205             final int moveId, final int callingUid, UserHandle user)
26206                     throws PackageManagerException {
26207         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
26208         final PackageManager pm = mContext.getPackageManager();
26209 
26210         final String currentVolumeUuid;
26211         final File codeFile;
26212         final InstallSource installSource;
26213         final String packageAbiOverride;
26214         final int appId;
26215         final String seinfo;
26216         final String label;
26217         final int targetSdkVersion;
26218         final PackageFreezer freezer;
26219         final int[] installedUserIds;
26220         final boolean isCurrentLocationExternal;
26221         final String fromCodePath;
26222 
26223         // reader
26224         synchronized (mLock) {
26225             final AndroidPackage pkg = mPackages.get(packageName);
26226             final PackageSetting ps = mSettings.getPackageLPr(packageName);
26227             if (pkg == null
26228                     || ps == null
26229                     || shouldFilterApplicationLocked(ps, callingUid, user.getIdentifier())) {
26230                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
26231             }
26232             if (pkg.isSystem()) {
26233                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
26234                         "Cannot move system application");
26235             }
26236 
26237             final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
26238             final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
26239                     com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
26240             if (isInternalStorage && !allow3rdPartyOnInternal) {
26241                 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
26242                         "3rd party apps are not allowed on internal storage");
26243             }
26244 
26245             currentVolumeUuid = ps.volumeUuid;
26246 
26247             final File probe = new File(pkg.getPath());
26248             final File probeOat = new File(probe, "oat");
26249             if (!probe.isDirectory() || !probeOat.isDirectory()) {
26250                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26251                         "Move only supported for modern cluster style installs");
26252             }
26253 
26254             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
26255                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26256                         "Package already moved to " + volumeUuid);
26257             }
26258             if (!pkg.isExternalStorage() && isPackageDeviceAdminOnAnyUser(packageName)) {
26259                 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
26260                         "Device admin cannot be moved");
26261             }
26262 
26263             if (mFrozenPackages.contains(packageName)) {
26264                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
26265                         "Failed to move already frozen package");
26266             }
26267 
26268             isCurrentLocationExternal = pkg.isExternalStorage();
26269             codeFile = new File(pkg.getPath());
26270             installSource = ps.installSource;
26271             packageAbiOverride = ps.cpuAbiOverrideString;
26272             appId = UserHandle.getAppId(pkg.getUid());
26273             seinfo = AndroidPackageUtils.getSeInfo(pkg, ps);
26274             label = String.valueOf(pm.getApplicationLabel(pkg.toAppInfoWithoutState()));
26275             targetSdkVersion = pkg.getTargetSdkVersion();
26276             freezer = freezePackage(packageName, "movePackageInternal");
26277             installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
26278             if (codeFile.getParentFile().getName().startsWith(RANDOM_DIR_PREFIX)) {
26279                 fromCodePath = codeFile.getParentFile().getAbsolutePath();
26280             } else {
26281                 fromCodePath = codeFile.getAbsolutePath();
26282             }
26283         }
26284 
26285         final Bundle extras = new Bundle();
26286         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
26287         extras.putString(Intent.EXTRA_TITLE, label);
26288         mMoveCallbacks.notifyCreated(moveId, extras);
26289 
26290         int installFlags;
26291         final boolean moveCompleteApp;
26292         final File measurePath;
26293 
26294         installFlags = INSTALL_INTERNAL;
26295         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
26296             moveCompleteApp = true;
26297             measurePath = Environment.getDataAppDirectory(volumeUuid);
26298         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
26299             moveCompleteApp = false;
26300             measurePath = storage.getPrimaryPhysicalVolume().getPath();
26301         } else {
26302             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
26303             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
26304                     || !volume.isMountedWritable()) {
26305                 freezer.close();
26306                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26307                         "Move location not mounted private volume");
26308             }
26309 
26310             moveCompleteApp = true;
26311             measurePath = Environment.getDataAppDirectory(volumeUuid);
26312         }
26313 
26314         // If we're moving app data around, we need all the users unlocked
26315         if (moveCompleteApp) {
26316             for (int userId : installedUserIds) {
26317                 if (StorageManager.isFileEncryptedNativeOrEmulated()
26318                         && !StorageManager.isUserKeyUnlocked(userId)) {
26319                     throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
26320                             "User " + userId + " must be unlocked");
26321                 }
26322             }
26323         }
26324 
26325         final PackageStats stats = new PackageStats(null, -1);
26326         synchronized (mInstaller) {
26327             for (int userId : installedUserIds) {
26328                 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
26329                     freezer.close();
26330                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26331                             "Failed to measure package size");
26332                 }
26333             }
26334         }
26335 
26336         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
26337                 + stats.dataSize);
26338 
26339         final long startFreeBytes = measurePath.getUsableSpace();
26340         final long sizeBytes;
26341         if (moveCompleteApp) {
26342             sizeBytes = stats.codeSize + stats.dataSize;
26343         } else {
26344             sizeBytes = stats.codeSize;
26345         }
26346 
26347         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
26348             freezer.close();
26349             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26350                     "Not enough free space to move");
26351         }
26352 
26353         mMoveCallbacks.notifyStatusChanged(moveId, 10);
26354 
26355         final CountDownLatch installedLatch = new CountDownLatch(1);
26356         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
26357             @Override
26358             public void onUserActionRequired(Intent intent) throws RemoteException {
26359                 throw new IllegalStateException();
26360             }
26361 
26362             @Override
26363             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
26364                     Bundle extras) throws RemoteException {
26365                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
26366                         + PackageManager.installStatusToString(returnCode, msg));
26367 
26368                 installedLatch.countDown();
26369                 freezer.close();
26370 
26371                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
26372                 switch (status) {
26373                     case PackageInstaller.STATUS_SUCCESS:
26374                         mMoveCallbacks.notifyStatusChanged(moveId,
26375                                 PackageManager.MOVE_SUCCEEDED);
26376                         logAppMovedStorage(packageName, isCurrentLocationExternal);
26377                         break;
26378                     case PackageInstaller.STATUS_FAILURE_STORAGE:
26379                         mMoveCallbacks.notifyStatusChanged(moveId,
26380                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
26381                         break;
26382                     default:
26383                         mMoveCallbacks.notifyStatusChanged(moveId,
26384                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
26385                         break;
26386                 }
26387             }
26388         };
26389 
26390         final MoveInfo move;
26391         if (moveCompleteApp) {
26392             // Kick off a thread to report progress estimates
26393             new Thread(() -> {
26394                 while (true) {
26395                     try {
26396                         if (installedLatch.await(1, TimeUnit.SECONDS)) {
26397                             break;
26398                         }
26399                     } catch (InterruptedException ignored) {
26400                     }
26401 
26402                     final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
26403                     final int progress = 10 + (int) MathUtils.constrain(
26404                             ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
26405                     mMoveCallbacks.notifyStatusChanged(moveId, progress);
26406                 }
26407             }).start();
26408 
26409             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
26410                     appId, seinfo, targetSdkVersion, fromCodePath);
26411         } else {
26412             move = null;
26413         }
26414 
26415         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
26416 
26417         final Message msg = mHandler.obtainMessage(INIT_COPY);
26418         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
26419         final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
26420         final ParseResult<PackageLite> ret = ApkLiteParseUtils.parsePackageLite(input,
26421                 new File(origin.resolvedPath), /* flags */ 0);
26422         final PackageLite lite = ret.isSuccess() ? ret.getResult() : null;
26423         final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
26424                 installSource, volumeUuid, user, packageAbiOverride, lite);
26425         params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
26426         msg.obj = params;
26427 
26428         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
26429                 System.identityHashCode(msg.obj));
26430         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
26431                 System.identityHashCode(msg.obj));
26432 
26433         mHandler.sendMessage(msg);
26434     }
26435 
26436     /**
26437      * Logs that an app has been moved from internal to external storage and vice versa.
26438      * @param packageName The package that was moved.
26439      */
26440     private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) {
26441         final AndroidPackage pkg;
26442         synchronized (mLock) {
26443             pkg = mPackages.get(packageName);
26444         }
26445         if (pkg == null) {
26446             return;
26447         }
26448 
26449         final StorageManager storage = mInjector.getSystemService(StorageManager.class);;
26450         VolumeInfo volume = storage.findVolumeByUuid(pkg.getStorageUuid().toString());
26451         int packageExternalStorageType = getPackageExternalStorageType(volume, pkg.isExternalStorage());
26452 
26453         if (!isPreviousLocationExternal && pkg.isExternalStorage()) {
26454             // Move from internal to external storage.
26455             FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
26456                     packageExternalStorageType,
26457                     FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
26458                     packageName);
26459         } else if (isPreviousLocationExternal && !pkg.isExternalStorage()) {
26460             // Move from external to internal storage.
26461             FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
26462                     packageExternalStorageType,
26463                     FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
26464                     packageName);
26465         }
26466     }
26467 
26468     @Override
26469     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
26470         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
26471 
26472         final int realMoveId = mNextMoveId.getAndIncrement();
26473         final Bundle extras = new Bundle();
26474         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
26475         mMoveCallbacks.notifyCreated(realMoveId, extras);
26476 
26477         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
26478             @Override
26479             public void onCreated(int moveId, Bundle extras) {
26480                 // Ignored
26481             }
26482 
26483             @Override
26484             public void onStatusChanged(int moveId, int status, long estMillis) {
26485                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
26486             }
26487         };
26488 
26489         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
26490         storage.setPrimaryStorageUuid(volumeUuid, callback);
26491         return realMoveId;
26492     }
26493 
26494     @Override
26495     public int getMoveStatus(int moveId) {
26496         mContext.enforceCallingOrSelfPermission(
26497                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
26498         return mMoveCallbacks.mLastStatus.get(moveId);
26499     }
26500 
26501     @Override
26502     public void registerMoveCallback(IPackageMoveObserver callback) {
26503         mContext.enforceCallingOrSelfPermission(
26504                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
26505         mMoveCallbacks.register(callback);
26506     }
26507 
26508     @Override
26509     public void unregisterMoveCallback(IPackageMoveObserver callback) {
26510         mContext.enforceCallingOrSelfPermission(
26511                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
26512         mMoveCallbacks.unregister(callback);
26513     }
26514 
26515     @Override
26516     public boolean setInstallLocation(int loc) {
26517         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
26518                 null);
26519         if (getInstallLocation() == loc) {
26520             return true;
26521         }
26522         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
26523                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
26524             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
26525                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
26526             return true;
26527         }
26528         return false;
26529    }
26530 
26531     @Override
26532     public int getInstallLocation() {
26533         // allow instant app access
26534         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
26535                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
26536                 PackageHelper.APP_INSTALL_AUTO);
26537     }
26538 
26539     /** Called by UserManagerService */
26540     void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) {
26541         synchronized (mLock) {
26542             mDirtyUsers.remove(userId);
26543             mUserNeedsBadging.delete(userId);
26544             mPermissionManager.onUserRemoved(userId);
26545             mSettings.removeUserLPw(userId);
26546             mPendingBroadcasts.remove(userId);
26547             mInstantAppRegistry.onUserRemovedLPw(userId);
26548             removeUnusedPackagesLPw(userManager, userId);
26549         }
26550     }
26551 
26552     /**
26553      * We're removing userId and would like to remove any downloaded packages
26554      * that are no longer in use by any other user.
26555      * @param userId the user being removed
26556      */
26557     @GuardedBy("mLock")
26558     private void removeUnusedPackagesLPw(UserManagerService userManager, final int userId) {
26559         final boolean DEBUG_CLEAN_APKS = false;
26560         int [] users = userManager.getUserIds();
26561         final int numPackages = mSettings.getPackagesLocked().size();
26562         for (int index = 0; index < numPackages; index++) {
26563             final PackageSetting ps = mSettings.getPackagesLocked().valueAt(index);
26564             if (ps.pkg == null) {
26565                 continue;
26566             }
26567             final String packageName = ps.pkg.getPackageName();
26568             // Skip over if system app or static shared library
26569             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
26570                     || !TextUtils.isEmpty(ps.pkg.getStaticSharedLibName())) {
26571                 continue;
26572             }
26573             if (DEBUG_CLEAN_APKS) {
26574                 Slog.i(TAG, "Checking package " + packageName);
26575             }
26576             boolean keep = shouldKeepUninstalledPackageLPr(packageName);
26577             if (keep) {
26578                 if (DEBUG_CLEAN_APKS) {
26579                     Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
26580                 }
26581             } else {
26582                 for (int i = 0; i < users.length; i++) {
26583                     if (users[i] != userId && ps.getInstalled(users[i])) {
26584                         keep = true;
26585                         if (DEBUG_CLEAN_APKS) {
26586                             Slog.i(TAG, "  Keeping package " + packageName + " for user "
26587                                     + users[i]);
26588                         }
26589                         break;
26590                     }
26591                 }
26592             }
26593             if (!keep) {
26594                 if (DEBUG_CLEAN_APKS) {
26595                     Slog.i(TAG, "  Removing package " + packageName);
26596                 }
26597                 //end run
26598                 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
26599                         userId, 0, true /*removedBySystem*/));
26600             }
26601         }
26602     }
26603 
26604     /**
26605      * Called by UserManagerService.
26606      *
26607      * @param userTypeInstallablePackages system packages that should be initially installed for
26608      *                                    this type of user, or {@code null} if all system packages
26609      *                                    should be installed
26610      * @param disallowedPackages packages that should not be initially installed. Takes precedence
26611      *                           over installablePackages.
26612      */
26613     void createNewUser(int userId, @Nullable Set<String> userTypeInstallablePackages,
26614             String[] disallowedPackages) {
26615         synchronized (mInstallLock) {
26616             mSettings.createNewUserLI(this, mInstaller, userId,
26617                     userTypeInstallablePackages, disallowedPackages);
26618         }
26619         synchronized (mLock) {
26620             scheduleWritePackageRestrictionsLocked(userId);
26621             scheduleWritePackageListLocked(userId);
26622             mAppsFilter.onUsersChanged();
26623         }
26624     }
26625 
26626     void onNewUserCreated(@UserIdInt int userId, boolean convertedFromPreCreated) {
26627         if (DEBUG_PERMISSIONS) {
26628             Slog.d(TAG, "onNewUserCreated(id=" + userId
26629                     + ", convertedFromPreCreated=" + convertedFromPreCreated + ")");
26630         }
26631         if (!convertedFromPreCreated || !readPermissionStateForUser(userId)) {
26632             mPermissionManager.onUserCreated(userId);
26633             mLegacyPermissionManager.grantDefaultPermissions(userId);
26634             mDomainVerificationManager.clearUser(userId);
26635         }
26636     }
26637 
26638     boolean readPermissionStateForUser(@UserIdInt int userId) {
26639         synchronized (mLock) {
26640             mPermissionManager.writeLegacyPermissionStateTEMP();
26641             mSettings.readPermissionStateForUserSyncLPr(userId);
26642             mPermissionManager.readLegacyPermissionStateTEMP();
26643             return mPmInternal.isPermissionUpgradeNeeded(userId);
26644         }
26645     }
26646 
26647     @Override
26648     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
26649         mContext.enforceCallingOrSelfPermission(
26650                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
26651                 "Only package verification agents can read the verifier device identity");
26652 
26653         synchronized (mLock) {
26654             return mSettings.getVerifierDeviceIdentityLPw();
26655         }
26656     }
26657 
26658     @Override
26659     public boolean isStorageLow() {
26660         // allow instant applications
26661         final long token = Binder.clearCallingIdentity();
26662         try {
26663             final DeviceStorageMonitorInternal
26664                     dsm = mInjector.getLocalService(DeviceStorageMonitorInternal.class);
26665             if (dsm != null) {
26666                 return dsm.isMemoryLow();
26667             } else {
26668                 return false;
26669             }
26670         } finally {
26671             Binder.restoreCallingIdentity(token);
26672         }
26673     }
26674 
26675     @Override
26676     public IPackageInstaller getPackageInstaller() {
26677         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
26678             return null;
26679         }
26680         return mInstallerService;
26681     }
26682 
26683     @Override
26684     public IArtManager getArtManager() {
26685         return mArtManagerService;
26686     }
26687 
26688     private boolean userNeedsBadging(int userId) {
26689         int index = mUserNeedsBadging.indexOfKey(userId);
26690         if (index < 0) {
26691             final UserInfo userInfo;
26692             final long token = Binder.clearCallingIdentity();
26693             try {
26694                 userInfo = mUserManager.getUserInfo(userId);
26695             } finally {
26696                 Binder.restoreCallingIdentity(token);
26697             }
26698             final boolean b;
26699             if (userInfo != null && userInfo.isManagedProfile()) {
26700                 b = true;
26701             } else {
26702                 b = false;
26703             }
26704             mUserNeedsBadging.put(userId, b);
26705             return b;
26706         }
26707         return mUserNeedsBadging.valueAt(index);
26708     }
26709 
26710     @Override
26711     public KeySet getKeySetByAlias(String packageName, String alias) {
26712         if (packageName == null || alias == null) {
26713             return null;
26714         }
26715         synchronized (mLock) {
26716             final AndroidPackage pkg = mPackages.get(packageName);
26717             if (pkg == null
26718                     || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
26719                     Binder.getCallingUid(), UserHandle.getCallingUserId())) {
26720                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
26721                 throw new IllegalArgumentException("Unknown package: " + packageName);
26722             }
26723             final KeySetManagerService ksms = mSettings.getKeySetManagerService();
26724             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
26725         }
26726     }
26727 
26728     @Override
26729     public KeySet getSigningKeySet(String packageName) {
26730         if (packageName == null) {
26731             return null;
26732         }
26733         synchronized (mLock) {
26734             final int callingUid = Binder.getCallingUid();
26735             final int callingUserId = UserHandle.getUserId(callingUid);
26736             final AndroidPackage pkg = mPackages.get(packageName);
26737             if (pkg == null
26738                     || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
26739                     callingUid, callingUserId)) {
26740                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName
26741                         + ", uid:" + callingUid);
26742                 throw new IllegalArgumentException("Unknown package: " + packageName);
26743             }
26744             if (pkg.getUid() != callingUid
26745                     && Process.SYSTEM_UID != callingUid) {
26746                 throw new SecurityException("May not access signing KeySet of other apps.");
26747             }
26748             final KeySetManagerService ksms = mSettings.getKeySetManagerService();
26749             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
26750         }
26751     }
26752 
26753     @Override
26754     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
26755         final int callingUid = Binder.getCallingUid();
26756         if (getInstantAppPackageName(callingUid) != null) {
26757             return false;
26758         }
26759         if (packageName == null || ks == null) {
26760             return false;
26761         }
26762         synchronized (mLock) {
26763             final AndroidPackage pkg = mPackages.get(packageName);
26764             if (pkg == null
26765                     || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
26766                     callingUid, UserHandle.getUserId(callingUid))) {
26767                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
26768                 throw new IllegalArgumentException("Unknown package: " + packageName);
26769             }
26770             IBinder ksh = ks.getToken();
26771             if (ksh instanceof KeySetHandle) {
26772                 final KeySetManagerService ksms = mSettings.getKeySetManagerService();
26773                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
26774             }
26775             return false;
26776         }
26777     }
26778 
26779     @Override
26780     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
26781         final int callingUid = Binder.getCallingUid();
26782         if (getInstantAppPackageName(callingUid) != null) {
26783             return false;
26784         }
26785         if (packageName == null || ks == null) {
26786             return false;
26787         }
26788         synchronized (mLock) {
26789             final AndroidPackage pkg = mPackages.get(packageName);
26790             if (pkg == null
26791                     || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
26792                     callingUid, UserHandle.getUserId(callingUid))) {
26793                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
26794                 throw new IllegalArgumentException("Unknown package: " + packageName);
26795             }
26796             IBinder ksh = ks.getToken();
26797             if (ksh instanceof KeySetHandle) {
26798                 final KeySetManagerService ksms = mSettings.getKeySetManagerService();
26799                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
26800             }
26801             return false;
26802         }
26803     }
26804 
26805     @GuardedBy("mLock")
26806     private void deletePackageIfUnusedLPr(final String packageName) {
26807         PackageSetting ps = mSettings.getPackageLPr(packageName);
26808         if (ps == null) {
26809             return;
26810         }
26811         if (!ps.isAnyInstalled(mUserManager.getUserIds())) {
26812             // TODO Implement atomic delete if package is unused
26813             // It is currently possible that the package will be deleted even if it is installed
26814             // after this method returns.
26815             mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
26816                     0, PackageManager.DELETE_ALL_USERS, true /*removedBySystem*/));
26817         }
26818     }
26819 
26820     private int verifyReplacingVersionCode(PackageInfoLite pkgLite,
26821             long requiredInstalledVersionCode, int installFlags) {
26822         String packageName = pkgLite.packageName;
26823         synchronized (mLock) {
26824             // Package which currently owns the data that the new package will own if installed.
26825             // If an app is uninstalled while keeping data (e.g. adb uninstall -k), installedPkg
26826             // will be null whereas dataOwnerPkg will contain information about the package
26827             // which was uninstalled while keeping its data.
26828             AndroidPackage dataOwnerPkg = mPackages.get(packageName);
26829             if (dataOwnerPkg  == null) {
26830                 PackageSetting ps = mSettings.getPackageLPr(packageName);
26831                 if (ps != null) {
26832                     dataOwnerPkg = ps.pkg;
26833                 }
26834             }
26835 
26836             if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
26837                 if (dataOwnerPkg == null) {
26838                     Slog.w(TAG, "Required installed version code was "
26839                             + requiredInstalledVersionCode
26840                             + " but package is not installed");
26841                     return PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
26842                 }
26843 
26844                 if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
26845                     Slog.w(TAG, "Required installed version code was "
26846                             + requiredInstalledVersionCode
26847                             + " but actual installed version is "
26848                             + dataOwnerPkg.getLongVersionCode());
26849                     return PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
26850                 }
26851             }
26852 
26853             if (dataOwnerPkg != null) {
26854                 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
26855                         dataOwnerPkg.isDebuggable())) {
26856                     try {
26857                         checkDowngrade(dataOwnerPkg, pkgLite);
26858                     } catch (PackageManagerException e) {
26859                         Slog.w(TAG, "Downgrade detected: " + e.getMessage());
26860                         return PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
26861                     }
26862                 }
26863             }
26864         }
26865         return PackageManager.INSTALL_SUCCEEDED;
26866     }
26867 
26868     /**
26869      * Check and throw if the given before/after packages would be considered a
26870      * downgrade.
26871      */
26872     private static void checkDowngrade(AndroidPackage before, PackageInfoLite after)
26873             throws PackageManagerException {
26874         if (after.getLongVersionCode() < before.getLongVersionCode()) {
26875             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
26876                     "Update version code " + after.versionCode + " is older than current "
26877                     + before.getLongVersionCode());
26878         } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
26879             if (after.baseRevisionCode < before.getBaseRevisionCode()) {
26880                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
26881                         "Update base revision code " + after.baseRevisionCode
26882                         + " is older than current " + before.getBaseRevisionCode());
26883             }
26884 
26885             if (!ArrayUtils.isEmpty(after.splitNames)) {
26886                 for (int i = 0; i < after.splitNames.length; i++) {
26887                     final String splitName = after.splitNames[i];
26888                     final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
26889                     if (j != -1) {
26890                         if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
26891                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
26892                                     "Update split " + splitName + " revision code "
26893                                     + after.splitRevisionCodes[i] + " is older than current "
26894                                     + before.getSplitRevisionCodes()[j]);
26895                         }
26896                     }
26897                 }
26898             }
26899         }
26900     }
26901 
26902     private static class MoveCallbacks extends Handler {
26903         private static final int MSG_CREATED = 1;
26904         private static final int MSG_STATUS_CHANGED = 2;
26905 
26906         private final RemoteCallbackList<IPackageMoveObserver>
26907                 mCallbacks = new RemoteCallbackList<>();
26908 
26909         private final SparseIntArray mLastStatus = new SparseIntArray();
26910 
26911         public MoveCallbacks(Looper looper) {
26912             super(looper);
26913         }
26914 
26915         public void register(IPackageMoveObserver callback) {
26916             mCallbacks.register(callback);
26917         }
26918 
26919         public void unregister(IPackageMoveObserver callback) {
26920             mCallbacks.unregister(callback);
26921         }
26922 
26923         @Override
26924         public void handleMessage(Message msg) {
26925             final SomeArgs args = (SomeArgs) msg.obj;
26926             final int n = mCallbacks.beginBroadcast();
26927             for (int i = 0; i < n; i++) {
26928                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
26929                 try {
26930                     invokeCallback(callback, msg.what, args);
26931                 } catch (RemoteException ignored) {
26932                 }
26933             }
26934             mCallbacks.finishBroadcast();
26935             args.recycle();
26936         }
26937 
26938         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
26939                 throws RemoteException {
26940             switch (what) {
26941                 case MSG_CREATED: {
26942                     callback.onCreated(args.argi1, (Bundle) args.arg2);
26943                     break;
26944                 }
26945                 case MSG_STATUS_CHANGED: {
26946                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
26947                     break;
26948                 }
26949             }
26950         }
26951 
26952         private void notifyCreated(int moveId, Bundle extras) {
26953             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
26954 
26955             final SomeArgs args = SomeArgs.obtain();
26956             args.argi1 = moveId;
26957             args.arg2 = extras;
26958             obtainMessage(MSG_CREATED, args).sendToTarget();
26959         }
26960 
26961         private void notifyStatusChanged(int moveId, int status) {
26962             notifyStatusChanged(moveId, status, -1);
26963         }
26964 
26965         private void notifyStatusChanged(int moveId, int status, long estMillis) {
26966             Slog.v(TAG, "Move " + moveId + " status " + status);
26967 
26968             final SomeArgs args = SomeArgs.obtain();
26969             args.argi1 = moveId;
26970             args.argi2 = status;
26971             args.arg3 = estMillis;
26972             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
26973 
26974             synchronized (mLastStatus) {
26975                 mLastStatus.put(moveId, status);
26976             }
26977         }
26978     }
26979 
26980     private final class PackageChangeObserverDeathRecipient implements IBinder.DeathRecipient {
26981         private final IPackageChangeObserver mObserver;
26982 
26983         PackageChangeObserverDeathRecipient(IPackageChangeObserver observer) {
26984             mObserver = observer;
26985         }
26986 
26987         @Override
26988         public void binderDied() {
26989             synchronized (mPackageChangeObservers) {
26990                 mPackageChangeObservers.remove(mObserver);
26991                 Log.d(TAG, "Size of mPackageChangeObservers after removing dead observer is "
26992                     + mPackageChangeObservers.size());
26993             }
26994         }
26995     }
26996 
26997     private class PackageManagerNative extends IPackageManagerNative.Stub {
26998         @Override
26999         public void registerPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
27000           synchronized (mPackageChangeObservers) {
27001             try {
27002                 observer.asBinder().linkToDeath(
27003                     new PackageChangeObserverDeathRecipient(observer), 0);
27004             } catch (RemoteException e) {
27005               Log.e(TAG, e.getMessage());
27006             }
27007             mPackageChangeObservers.add(observer);
27008             Log.d(TAG, "Size of mPackageChangeObservers after registry is "
27009                 + mPackageChangeObservers.size());
27010           }
27011         }
27012 
27013         @Override
27014         public void unregisterPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
27015           synchronized (mPackageChangeObservers) {
27016             mPackageChangeObservers.remove(observer);
27017             Log.d(TAG, "Size of mPackageChangeObservers after unregistry is "
27018                 + mPackageChangeObservers.size());
27019           }
27020         }
27021 
27022         @Override
27023         public String[] getAllPackages() {
27024             return PackageManagerService.this.getAllPackages().toArray(new String[0]);
27025         }
27026 
27027         @Override
27028         public String[] getNamesForUids(int[] uids) throws RemoteException {
27029             String[] names = null;
27030             String[] results = null;
27031             try {
27032                 if (uids == null || uids.length == 0) {
27033                     return null;
27034                 }
27035                 names = PackageManagerService.this.getNamesForUids(uids);
27036                 results = (names != null) ? names : new String[uids.length];
27037                 // massage results so they can be parsed by the native binder
27038                 for (int i = results.length - 1; i >= 0; --i) {
27039                     if (results[i] == null) {
27040                         results[i] = "";
27041                     }
27042                 }
27043                 return results;
27044             } catch (Throwable t) {
27045                 // STOPSHIP(186558987): revert addition of try/catch/log
27046                 Slog.e(TAG, "uids: " + Arrays.toString(uids));
27047                 Slog.e(TAG, "names: " + Arrays.toString(names));
27048                 Slog.e(TAG, "results: " + Arrays.toString(results));
27049                 Slog.e(TAG, "throwing exception", t);
27050                 throw t;
27051             }
27052         }
27053 
27054         // NB: this differentiates between preloads and sideloads
27055         @Override
27056         public String getInstallerForPackage(String packageName) throws RemoteException {
27057             final String installerName = getInstallerPackageName(packageName);
27058             if (!TextUtils.isEmpty(installerName)) {
27059                 return installerName;
27060             }
27061             // differentiate between preload and sideload
27062             int callingUser = UserHandle.getUserId(Binder.getCallingUid());
27063             ApplicationInfo appInfo = getApplicationInfo(packageName,
27064                                     /*flags*/ 0,
27065                                     /*userId*/ callingUser);
27066             if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
27067                 return "preload";
27068             }
27069             return "";
27070         }
27071 
27072         @Override
27073         public long getVersionCodeForPackage(String packageName) throws RemoteException {
27074             try {
27075                 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
27076                 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
27077                 if (pInfo != null) {
27078                     return pInfo.getLongVersionCode();
27079                 }
27080             } catch (Exception e) {
27081             }
27082             return 0;
27083         }
27084 
27085         @Override
27086         public int getTargetSdkVersionForPackage(String packageName) throws RemoteException {
27087             int targetSdk = getTargetSdkVersion(packageName);
27088             if (targetSdk != -1) {
27089                 return targetSdk;
27090             }
27091 
27092             throw new RemoteException("Couldn't get targetSdkVersion for package " + packageName);
27093         }
27094 
27095         @Override
27096         public boolean isPackageDebuggable(String packageName) throws RemoteException {
27097             int callingUser = UserHandle.getCallingUserId();
27098             ApplicationInfo appInfo = getApplicationInfo(packageName, 0, callingUser);
27099             if (appInfo != null) {
27100                 return (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
27101             }
27102 
27103             throw new RemoteException("Couldn't get debug flag for package " + packageName);
27104         }
27105 
27106         @Override
27107         public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
27108                 throws RemoteException {
27109             int callingUser = UserHandle.getUserId(Binder.getCallingUid());
27110             boolean[] results = new boolean[packageNames.length];
27111             for (int i = results.length - 1; i >= 0; --i) {
27112                 ApplicationInfo appInfo = getApplicationInfo(packageNames[i], 0, callingUser);
27113                 results[i] = appInfo == null ? false : appInfo.isAudioPlaybackCaptureAllowed();
27114             }
27115             return results;
27116         }
27117 
27118         @Override
27119         public int getLocationFlags(String packageName) throws RemoteException {
27120             int callingUser = UserHandle.getUserId(Binder.getCallingUid());
27121             ApplicationInfo appInfo = getApplicationInfo(packageName,
27122                     /*flags*/ 0,
27123                     /*userId*/ callingUser);
27124             if (appInfo == null) {
27125                 throw new RemoteException(
27126                         "Couldn't get ApplicationInfo for package " + packageName);
27127             }
27128             return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
27129                     | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
27130                     | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
27131         }
27132 
27133         @Override
27134         public String getModuleMetadataPackageName() throws RemoteException {
27135             return PackageManagerService.this.mModuleInfoProvider.getPackageName();
27136         }
27137 
27138         @Override
27139         public boolean hasSha256SigningCertificate(String packageName, byte[] certificate)
27140                 throws RemoteException {
27141             return PackageManagerService.this.hasSigningCertificate(
27142                 packageName, certificate, CERT_INPUT_SHA256);
27143         }
27144 
27145         @Override
27146         public boolean hasSystemFeature(String featureName, int version) {
27147             return PackageManagerService.this.hasSystemFeature(featureName, version);
27148         }
27149     }
27150 
27151     private AndroidPackage getPackage(String packageName) {
27152         return mComputer.getPackage(packageName);
27153     }
27154 
27155     private AndroidPackage getPackage(int uid) {
27156         return mComputer.getPackage(uid);
27157     }
27158 
27159     private SigningDetails getSigningDetails(@NonNull String packageName) {
27160         return mComputer.getSigningDetails(packageName);
27161     }
27162 
27163     private SigningDetails getSigningDetails(int uid) {
27164         return mComputer.getSigningDetails(uid);
27165     }
27166 
27167     private boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
27168         return mComputer.filterAppAccess(pkg, callingUid, userId);
27169     }
27170 
27171     private boolean filterAppAccess(String packageName, int callingUid, int userId) {
27172         return mComputer.filterAppAccess(packageName, callingUid, userId);
27173     }
27174 
27175     private class PackageManagerInternalImpl extends PackageManagerInternal {
27176         @Override
27177         public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
27178                 int callingUid) {
27179             return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
27180                     callingUid);
27181         }
27182 
27183         @Override
27184         public boolean isPlatformSigned(String packageName) {
27185             PackageSetting packageSetting = mSettings.getPackageLPr(packageName);
27186             if (packageSetting == null) {
27187                 return false;
27188             }
27189             AndroidPackage pkg = packageSetting.pkg;
27190             if (pkg == null) {
27191                 // May happen if package in on a removable sd card
27192                 return false;
27193             }
27194             return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails())
27195                     || mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(),
27196                     PackageParser.SigningDetails.CertCapabilities.PERMISSION);
27197         }
27198 
27199         @Override
27200         public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
27201             SigningDetails sd = getSigningDetails(packageName);
27202             if (sd == null) {
27203                 return false;
27204             }
27205             return sd.hasSha256Certificate(restoringFromSigHash,
27206                     SigningDetails.CertCapabilities.INSTALLED_DATA);
27207         }
27208 
27209         @Override
27210         public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
27211             SigningDetails sd = getSigningDetails(packageName);
27212             if (sd == null) {
27213                 return false;
27214             }
27215             return sd.hasCertificate(restoringFromSig,
27216                     SigningDetails.CertCapabilities.INSTALLED_DATA);
27217         }
27218 
27219         @Override
27220         public boolean hasSignatureCapability(int serverUid, int clientUid,
27221                 @SigningDetails.CertCapabilities int capability) {
27222             SigningDetails serverSigningDetails = getSigningDetails(serverUid);
27223             SigningDetails clientSigningDetails = getSigningDetails(clientUid);
27224             return serverSigningDetails.checkCapability(clientSigningDetails, capability)
27225                     || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);
27226 
27227         }
27228 
27229         private SigningDetails getSigningDetails(@NonNull String packageName) {
27230             return PackageManagerService.this.getSigningDetails(packageName);
27231         }
27232 
27233         private SigningDetails getSigningDetails(int uid) {
27234             return PackageManagerService.this.getSigningDetails(uid);
27235         }
27236 
27237         @Override
27238         public boolean isInstantApp(String packageName, int userId) {
27239             return PackageManagerService.this.isInstantApp(packageName, userId);
27240         }
27241 
27242         @Override
27243         public String getInstantAppPackageName(int uid) {
27244             return PackageManagerService.this.getInstantAppPackageName(uid);
27245         }
27246 
27247         @Override
27248         public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
27249             return PackageManagerService.this.filterAppAccess(pkg, callingUid, userId);
27250         }
27251 
27252         @Override
27253         public boolean filterAppAccess(String packageName, int callingUid, int userId) {
27254             return PackageManagerService.this.filterAppAccess(packageName, callingUid, userId);
27255         }
27256 
27257         @Override
27258         public AndroidPackage getPackage(String packageName) {
27259             return PackageManagerService.this.getPackage(packageName);
27260         }
27261 
27262         @Override
27263         public AndroidPackage getPackage(int uid) {
27264             return PackageManagerService.this.getPackage(uid);
27265         }
27266 
27267         @Nullable
27268         @Override
27269         public PackageSetting getPackageSetting(String packageName) {
27270             return PackageManagerService.this.getPackageSetting(packageName);
27271         }
27272 
27273         @Override
27274         public PackageList getPackageList(PackageListObserver observer) {
27275             synchronized (mLock) {
27276                 final int N = mPackages.size();
27277                 final ArrayList<String> list = new ArrayList<>(N);
27278                 for (int i = 0; i < N; i++) {
27279                     list.add(mPackages.keyAt(i));
27280                 }
27281                 final PackageList packageList = new PackageList(list, observer);
27282                 if (observer != null) {
27283                     mPackageListObservers.add(packageList);
27284                 }
27285                 return packageList;
27286             }
27287         }
27288 
27289         @Override
27290         public void removePackageListObserver(PackageListObserver observer) {
27291             synchronized (mLock) {
27292                 mPackageListObservers.remove(observer);
27293             }
27294         }
27295 
27296         @Override
27297         public PackageSetting getDisabledSystemPackage(@NonNull String packageName) {
27298             synchronized (mLock) {
27299                 return mSettings.getDisabledSystemPkgLPr(packageName);
27300             }
27301         }
27302 
27303         @Override
27304         public @Nullable
27305         String getDisabledSystemPackageName(@NonNull String packageName) {
27306             PackageSetting disabledPkgSetting = (PackageSetting) getDisabledSystemPackage(
27307                     packageName);
27308             AndroidPackage disabledPkg = disabledPkgSetting == null ? null : disabledPkgSetting.pkg;
27309             return disabledPkg == null ? null : disabledPkg.getPackageName();
27310         }
27311 
27312         /**
27313          * Only keep package names that refer to {@link PackageParser.Package#isSystem system}
27314          * packages.
27315          *
27316          * @param pkgNames The packages to filter
27317          *
27318          * @return The filtered packages
27319          */
27320         private @NonNull String[] filterOnlySystemPackages(@Nullable String... pkgNames) {
27321             if (pkgNames == null) {
27322                 return ArrayUtils.emptyArray(String.class);
27323             }
27324 
27325             ArrayList<String> systemPackageNames = new ArrayList<>(pkgNames.length);
27326 
27327             for (String pkgName: pkgNames) {
27328                 synchronized (mLock) {
27329                     if (pkgName == null) {
27330                         continue;
27331                     }
27332 
27333                     AndroidPackage pkg = getPackage(pkgName);
27334                     if (pkg == null) {
27335                         Log.w(TAG, "Could not find package " + pkgName);
27336                         continue;
27337                     }
27338 
27339                     if (!pkg.isSystem()) {
27340                         Log.w(TAG, pkgName + " is not system");
27341                         continue;
27342                     }
27343 
27344                     systemPackageNames.add(pkgName);
27345                 }
27346             }
27347 
27348             return systemPackageNames.toArray(new String[]{});
27349         }
27350 
27351         @Override
27352         public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
27353             return getKnownPackageNamesInternal(knownPackage, userId);
27354         }
27355 
27356         private String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
27357             switch (knownPackage) {
27358                 case PackageManagerInternal.PACKAGE_BROWSER:
27359                     return new String[] { mDefaultAppProvider.getDefaultBrowser(userId) };
27360                 case PackageManagerInternal.PACKAGE_INSTALLER:
27361                     return filterOnlySystemPackages(mRequiredInstallerPackage);
27362                 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
27363                     return filterOnlySystemPackages(mSetupWizardPackage);
27364                 case PackageManagerInternal.PACKAGE_SYSTEM:
27365                     return new String[]{"android"};
27366                 case PackageManagerInternal.PACKAGE_VERIFIER:
27367                     return filterOnlySystemPackages(mRequiredVerifierPackage);
27368                 case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
27369                     return filterOnlySystemPackages(
27370                             mDefaultTextClassifierPackage, mSystemTextClassifierPackageName);
27371                 case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
27372                     return filterOnlySystemPackages(mRequiredPermissionControllerPackage);
27373                 case PackageManagerInternal.PACKAGE_DOCUMENTER:
27374                     return filterOnlySystemPackages(mDocumenterPackage);
27375                 case PackageManagerInternal.PACKAGE_CONFIGURATOR:
27376                     return filterOnlySystemPackages(mConfiguratorPackage);
27377                 case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER:
27378                     return filterOnlySystemPackages(mIncidentReportApproverPackage);
27379                 case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
27380                     return filterOnlySystemPackages(mAppPredictionServicePackage);
27381                 case PackageManagerInternal.PACKAGE_COMPANION:
27382                     return filterOnlySystemPackages(COMPANION_PACKAGE_NAME);
27383                 case PackageManagerInternal.PACKAGE_RETAIL_DEMO:
27384                     return TextUtils.isEmpty(mRetailDemoPackage)
27385                             ? ArrayUtils.emptyArray(String.class)
27386                             : new String[] {mRetailDemoPackage};
27387                 case PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE:
27388                     return filterOnlySystemPackages(getOverlayConfigSignaturePackageName());
27389                 case PackageManagerInternal.PACKAGE_RECENTS:
27390                     return filterOnlySystemPackages(mRecentsPackage);
27391                 default:
27392                     return ArrayUtils.emptyArray(String.class);
27393             }
27394         }
27395 
27396         @Override
27397         public boolean isResolveActivityComponent(ComponentInfo component) {
27398             return mResolveActivity.packageName.equals(component.packageName)
27399                     && mResolveActivity.name.equals(component.name);
27400         }
27401 
27402         @Override
27403         public void setKeepUninstalledPackages(final List<String> packageList) {
27404             PackageManagerService.this.setKeepUninstalledPackagesInternal(packageList);
27405         }
27406 
27407         @Override
27408         public boolean isPermissionsReviewRequired(String packageName, int userId) {
27409             return mPermissionManager.isPermissionsReviewRequired(packageName, userId);
27410         }
27411 
27412         @Override
27413         public PackageInfo getPackageInfo(
27414                 String packageName, int flags, int filterCallingUid, int userId) {
27415             return PackageManagerService.this
27416                     .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
27417                             flags, filterCallingUid, userId);
27418         }
27419 
27420         @Override
27421         public long getCeDataInode(String packageName, int userId) {
27422             synchronized (mLock) {
27423                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27424                 if (ps != null) {
27425                     return ps.getCeDataInode(userId);
27426                 }
27427                 return 0;
27428             }
27429         }
27430 
27431         @Override
27432         public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
27433             synchronized (mLock) {
27434                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27435                 final Bundle allExtras = new Bundle();
27436                 if (ps != null) {
27437                     final PackageUserState pus = ps.readUserState(userId);
27438                     if (pus.suspended) {
27439                         for (int i = 0; i < pus.suspendParams.size(); i++) {
27440                             final PackageUserState.SuspendParams params =
27441                                     pus.suspendParams.valueAt(i);
27442                             if (params != null && params.launcherExtras != null) {
27443                                 allExtras.putAll(params.launcherExtras);
27444                             }
27445                         }
27446                     }
27447 
27448                 }
27449                 return (allExtras.size() > 0) ? allExtras : null;
27450             }
27451         }
27452 
27453         @Override
27454         public boolean isPackageSuspended(String packageName, int userId) {
27455             synchronized (mLock) {
27456                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27457                 return (ps != null) ? ps.getSuspended(userId) : false;
27458             }
27459         }
27460 
27461         @Override
27462         public void removeAllNonSystemPackageSuspensions(int userId) {
27463             final String[] allPackages;
27464             synchronized (mLock) {
27465                 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
27466             }
27467             PackageManagerService.this.removeSuspensionsBySuspendingPackage(allPackages,
27468                     (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
27469                     userId);
27470         }
27471 
27472         @Override
27473         public void removeNonSystemPackageSuspensions(String packageName, int userId) {
27474             PackageManagerService.this.removeSuspensionsBySuspendingPackage(
27475                     new String[]{packageName},
27476                     (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
27477                     userId);
27478         }
27479 
27480         @Override
27481         public void flushPackageRestrictions(int userId) {
27482             synchronized (mLock) {
27483                 PackageManagerService.this.flushPackageRestrictionsAsUserInternalLocked(userId);
27484             }
27485         }
27486 
27487         @Override
27488         public void removeDistractingPackageRestrictions(String packageName, int userId) {
27489             PackageManagerService.this.removeDistractingPackageRestrictions(
27490                     new String[]{packageName}, userId);
27491         }
27492 
27493         @Override
27494         public void removeAllDistractingPackageRestrictions(int userId) {
27495             PackageManagerService.this.removeAllDistractingPackageRestrictions(userId);
27496         }
27497 
27498         @Override
27499         public String getSuspendingPackage(String suspendedPackage, int userId) {
27500             synchronized (mLock) {
27501                 final PackageSetting ps = mSettings.getPackageLPr(suspendedPackage);
27502                 if (ps != null) {
27503                     final PackageUserState pus = ps.readUserState(userId);
27504                     if (pus.suspended) {
27505                         String suspendingPackage = null;
27506                         for (int i = 0; i < pus.suspendParams.size(); i++) {
27507                             suspendingPackage = pus.suspendParams.keyAt(i);
27508                             if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
27509                                 return suspendingPackage;
27510                             }
27511                         }
27512                         return suspendingPackage;
27513                     }
27514                 }
27515                 return null;
27516             }
27517         }
27518 
27519         @Override
27520         public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
27521                 String suspendingPackage, int userId) {
27522             synchronized (mLock) {
27523                 final PackageSetting ps = mSettings.getPackageLPr(suspendedPackage);
27524                 if (ps != null) {
27525                     final PackageUserState pus = ps.readUserState(userId);
27526                     if (pus.suspended) {
27527                         final PackageUserState.SuspendParams suspendParams =
27528                                 pus.suspendParams.get(suspendingPackage);
27529                         return (suspendParams != null) ? suspendParams.dialogInfo : null;
27530                     }
27531                 }
27532             }
27533             return null;
27534         }
27535 
27536         @Override
27537         public int getDistractingPackageRestrictions(String packageName, int userId) {
27538             synchronized (mLock) {
27539                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27540                 return (ps != null) ? ps.getDistractionFlags(userId) : RESTRICTION_NONE;
27541             }
27542         }
27543 
27544         @Override
27545         public int getPackageUid(String packageName, int flags, int userId) {
27546             return PackageManagerService.this
27547                     .getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
27548         }
27549 
27550         @Override
27551         public ApplicationInfo getApplicationInfo(
27552                 String packageName, int flags, int filterCallingUid, int userId) {
27553             return PackageManagerService.this
27554                     .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
27555         }
27556 
27557         @Override
27558         public ActivityInfo getActivityInfo(
27559                 ComponentName component, int flags, int filterCallingUid, int userId) {
27560             return PackageManagerService.this
27561                     .getActivityInfoInternal(component, flags, filterCallingUid, userId);
27562         }
27563 
27564         @Override
27565         public List<ResolveInfo> queryIntentActivities(
27566                 Intent intent, String resolvedType, int flags, int filterCallingUid, int userId) {
27567             return PackageManagerService.this
27568                     .queryIntentActivitiesInternal(intent, resolvedType, flags, 0, filterCallingUid,
27569                             userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
27570         }
27571 
27572         @Override
27573         public List<ResolveInfo> queryIntentServices(
27574                 Intent intent, int flags, int callingUid, int userId) {
27575             final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
27576             return PackageManagerService.this
27577                     .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
27578                             false);
27579         }
27580 
27581         @Override
27582         public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
27583                 int userId) {
27584             return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
27585         }
27586 
27587         @Override
27588         public ComponentName getDefaultHomeActivity(int userId) {
27589             return PackageManagerService.this.getDefaultHomeActivity(userId);
27590         }
27591 
27592         @Override
27593         public ComponentName getSystemUiServiceComponent() {
27594             return ComponentName.unflattenFromString(mContext.getResources().getString(
27595                     com.android.internal.R.string.config_systemUIServiceComponent));
27596         }
27597 
27598         @Override
27599         public void setDeviceAndProfileOwnerPackages(
27600                 int deviceOwnerUserId, String deviceOwnerPackage,
27601                 SparseArray<String> profileOwnerPackages) {
27602             mProtectedPackages.setDeviceAndProfileOwnerPackages(
27603                     deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
27604 
27605             final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
27606             if (deviceOwnerPackage != null) {
27607                 usersWithPoOrDo.add(deviceOwnerUserId);
27608             }
27609             final int sz = profileOwnerPackages.size();
27610             for (int i = 0; i < sz; i++) {
27611                 if (profileOwnerPackages.valueAt(i) != null) {
27612                     usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
27613                 }
27614             }
27615         }
27616 
27617         @Override
27618         public void setDeviceOwnerProtectedPackages(
27619                 String deviceOwnerPackageName, List<String> packageNames) {
27620             mProtectedPackages.setDeviceOwnerProtectedPackages(
27621                     deviceOwnerPackageName, packageNames);
27622         }
27623 
27624         @Override
27625         public boolean isPackageDataProtected(int userId, String packageName) {
27626             return mProtectedPackages.isPackageDataProtected(userId, packageName);
27627         }
27628 
27629         @Override
27630         public boolean isPackageStateProtected(String packageName, int userId) {
27631             return mProtectedPackages.isPackageStateProtected(userId, packageName);
27632         }
27633 
27634         @Override
27635         public boolean isPackageEphemeral(int userId, String packageName) {
27636             synchronized (mLock) {
27637                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27638                 return ps != null ? ps.getInstantApp(userId) : false;
27639             }
27640         }
27641 
27642         @Override
27643         public boolean wasPackageEverLaunched(String packageName, int userId) {
27644             synchronized (mLock) {
27645                 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
27646             }
27647         }
27648 
27649         // TODO(188814480) should be able to remove the NPE check when snapshot
27650         // "recursion" is fixed.
27651         @Override
27652         public boolean isEnabledAndMatches(ParsedMainComponent component, int flags, int userId) {
27653             synchronized (mLock) {
27654                 AndroidPackage pkg = getPackage(component.getPackageName());
27655                 if (pkg == null) {
27656                     return false;
27657                 } else {
27658                     return mSettings.isEnabledAndMatchLPr(pkg, component, flags, userId);
27659                 }
27660             }
27661         }
27662 
27663         @Override
27664         public boolean userNeedsBadging(int userId) {
27665             synchronized (mLock) {
27666                 return PackageManagerService.this.userNeedsBadging(userId);
27667             }
27668         }
27669 
27670         @Override
27671         public String getNameForUid(int uid) {
27672             return PackageManagerService.this.getNameForUid(uid);
27673         }
27674 
27675         @Override
27676         public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
27677                 Intent origIntent, String resolvedType, String callingPackage,
27678                 @Nullable String callingFeatureId, boolean isRequesterInstantApp,
27679                 Bundle verificationBundle, int userId) {
27680             PackageManagerService.this.requestInstantAppResolutionPhaseTwo(responseObj, origIntent,
27681                     resolvedType, callingPackage, callingFeatureId, isRequesterInstantApp,
27682                     verificationBundle, userId);
27683         }
27684 
27685         @Override
27686         public void grantImplicitAccess(int userId, Intent intent,
27687                 int recipientAppId, int visibleUid, boolean direct) {
27688             synchronized (mLock) {
27689                 final AndroidPackage visiblePackage = getPackage(visibleUid);
27690                 final int recipientUid = UserHandle.getUid(userId, recipientAppId);
27691                 if (visiblePackage == null || getPackage(recipientUid) == null) {
27692                     return;
27693                 }
27694 
27695                 final boolean instantApp =
27696                         isInstantAppInternal(visiblePackage.getPackageName(), userId, visibleUid);
27697                 final boolean accessGranted;
27698                 if (instantApp) {
27699                     if (!direct) {
27700                         // if the interaction that lead to this granting access to an instant app
27701                         // was indirect (i.e.: URI permission grant), do not actually execute the
27702                         // grant.
27703                         return;
27704                     }
27705                     accessGranted = mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
27706                             recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
27707                 } else {
27708                     accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid);
27709                 }
27710                 if (accessGranted) {
27711                     ApplicationPackageManager.invalidateGetPackagesForUidCache();
27712                 }
27713             }
27714         }
27715 
27716         @Override
27717         public boolean isInstantAppInstallerComponent(ComponentName component) {
27718             synchronized (mLock) {
27719                 return mInstantAppInstallerActivity != null
27720                         && mInstantAppInstallerActivity.getComponentName().equals(component);
27721             }
27722         }
27723 
27724         @Override
27725         public void pruneInstantApps() {
27726             mInstantAppRegistry.pruneInstantApps();
27727         }
27728 
27729         @Override
27730         public void pruneCachedApksInApex(@NonNull List<PackageInfo> apexPackages) {
27731             if (mCacheDir == null) {
27732                 return;
27733             }
27734 
27735             final PackageCacher cacher = new PackageCacher(mCacheDir);
27736             synchronized (mLock) {
27737                 for (int i = 0, size = apexPackages.size(); i < size; i++) {
27738                     final List<String> apkNames =
27739                             mApexManager.getApksInApex(apexPackages.get(i).packageName);
27740                     for (int j = 0, apksInApex = apkNames.size(); j < apksInApex; j++) {
27741                         final AndroidPackage pkg = getPackage(apkNames.get(j));
27742                         cacher.cleanCachedResult(new File(pkg.getPath()));
27743                     }
27744                 }
27745             }
27746         }
27747 
27748         @Override
27749         public String getSetupWizardPackageName() {
27750             return mSetupWizardPackage;
27751         }
27752 
27753         public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
27754             if (policy != null) {
27755                 mExternalSourcesPolicy = policy;
27756             }
27757         }
27758 
27759         @Override
27760         public boolean isPackagePersistent(String packageName) {
27761             synchronized (mLock) {
27762                 AndroidPackage pkg = mPackages.get(packageName);
27763                 return pkg != null && pkg.isSystem() && pkg.isPersistent();
27764             }
27765         }
27766 
27767         @Override
27768         public List<PackageInfo> getOverlayPackages(int userId) {
27769             final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
27770             synchronized (mLock) {
27771                 for (AndroidPackage p : mPackages.values()) {
27772                     if (p.getOverlayTarget() != null) {
27773                         PackageInfo pkg = generatePackageInfo(getPackageSetting(p.getPackageName()),
27774                                 0, userId);
27775                         if (pkg != null) {
27776                             overlayPackages.add(pkg);
27777                         }
27778                     }
27779                 }
27780             }
27781             return overlayPackages;
27782         }
27783 
27784         @Override
27785         public List<String> getTargetPackageNames(int userId) {
27786             List<String> targetPackages = new ArrayList<>();
27787             synchronized (mLock) {
27788                 for (AndroidPackage p : mPackages.values()) {
27789                     if (p.getOverlayTarget() == null) {
27790                         targetPackages.add(p.getPackageName());
27791                     }
27792                 }
27793             }
27794             return targetPackages;
27795         }
27796 
27797         @Override
27798         public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
27799                 @Nullable OverlayPaths overlayPaths,
27800                 @NonNull Set<String> outUpdatedPackageNames) {
27801             boolean modified = false;
27802             synchronized (mLock) {
27803                 final AndroidPackage targetPkg = mPackages.get(targetPackageName);
27804                 if (targetPackageName == null || targetPkg == null) {
27805                     Slog.e(TAG, "failed to find package " + targetPackageName);
27806                     return false;
27807                 }
27808 
27809                 if (targetPkg.getLibraryNames() != null) {
27810                     // Set the overlay paths for dependencies of the shared library.
27811                     for (final String libName : targetPkg.getLibraryNames()) {
27812                         final SharedLibraryInfo info = getSharedLibraryInfoLPr(libName,
27813                                 SharedLibraryInfo.VERSION_UNDEFINED);
27814                         if (info == null) {
27815                             continue;
27816                         }
27817                         final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
27818                                 info, 0, Process.SYSTEM_UID, userId);
27819                         if (dependents == null) {
27820                             continue;
27821                         }
27822                         for (final VersionedPackage dependent : dependents) {
27823                             final PackageSetting ps = mSettings.getPackageLPr(
27824                                     dependent.getPackageName());
27825                             if (ps == null) {
27826                                 continue;
27827                             }
27828                             if (ps.setOverlayPathsForLibrary(libName, overlayPaths, userId)) {
27829                                 outUpdatedPackageNames.add(dependent.getPackageName());
27830                                 modified = true;
27831                             }
27832                         }
27833                     }
27834                 }
27835 
27836                 final PackageSetting ps = mSettings.getPackageLPr(targetPackageName);
27837                 if (ps.setOverlayPaths(overlayPaths, userId)) {
27838                     outUpdatedPackageNames.add(targetPackageName);
27839                     modified = true;
27840                 }
27841 
27842                 if (modified) {
27843                     invalidatePackageInfoCache();
27844                 }
27845             }
27846 
27847             return true;
27848         }
27849 
27850         @Override
27851         public ResolveInfo resolveIntent(Intent intent, String resolvedType,
27852                 int flags, int privateResolveFlags, int userId, boolean resolveForStart,
27853                 int filterCallingUid) {
27854             return resolveIntentInternal(
27855                     intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
27856                     filterCallingUid);
27857         }
27858 
27859         @Override
27860         public ResolveInfo resolveService(Intent intent, String resolvedType,
27861                 int flags, int userId, int callingUid) {
27862             return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
27863         }
27864 
27865         @Override
27866         public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
27867             return PackageManagerService.this.resolveContentProviderInternal(
27868                     name, flags, userId);
27869         }
27870 
27871         @Override
27872         public ProviderInfo resolveContentProvider(String name, int flags, int userId,
27873                 int callingUid) {
27874             return PackageManagerService.this.resolveContentProviderInternal(
27875                     name, flags, userId, callingUid);
27876         }
27877 
27878         @Override
27879         public void addIsolatedUid(int isolatedUid, int ownerUid) {
27880             synchronized (mLock) {
27881                 mIsolatedOwners.put(isolatedUid, ownerUid);
27882             }
27883         }
27884 
27885         @Override
27886         public void removeIsolatedUid(int isolatedUid) {
27887             synchronized (mLock) {
27888                 mIsolatedOwners.delete(isolatedUid);
27889             }
27890         }
27891 
27892         @Override
27893         public int getUidTargetSdkVersion(int uid) {
27894             synchronized (mLock) {
27895                 return getUidTargetSdkVersionLockedLPr(uid);
27896             }
27897         }
27898 
27899         @Override
27900         public int getPackageTargetSdkVersion(String packageName) {
27901             synchronized (mLock) {
27902                 return getPackageTargetSdkVersionLockedLPr(packageName);
27903             }
27904         }
27905 
27906         @Override
27907         public boolean canAccessInstantApps(int callingUid, int userId) {
27908             return PackageManagerService.this.canViewInstantApps(callingUid, userId);
27909         }
27910 
27911         @Override
27912         public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
27913             synchronized (mLock) {
27914                 final PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
27915                 return ps != null && !PackageManagerService.this.shouldFilterApplicationLocked(
27916                         ps, callingUid, component, TYPE_UNKNOWN, userId);
27917             }
27918         }
27919 
27920         @Override
27921         public boolean hasInstantApplicationMetadata(String packageName, int userId) {
27922             synchronized (mLock) {
27923                 return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
27924             }
27925         }
27926 
27927         @Override
27928         public void notifyPackageUse(String packageName, int reason) {
27929             synchronized (mLock) {
27930                 PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
27931             }
27932         }
27933 
27934         @Override
27935         public SparseArray<String> getAppsWithSharedUserIds() {
27936             synchronized (mLock) {
27937                 return getAppsWithSharedUserIdsLocked();
27938             }
27939         }
27940 
27941         @Override
27942         @NonNull
27943         public String[] getSharedUserPackagesForPackage(String packageName, int userId) {
27944             synchronized (mLock) {
27945                 return getSharedUserPackagesForPackageLocked(packageName, userId);
27946             }
27947         }
27948 
27949         @Override
27950         public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
27951             synchronized (mLock) {
27952                 return getProcessesForUidLocked(uid);
27953             }
27954         }
27955 
27956         @Override
27957         public int[] getPermissionGids(String permissionName, int userId) {
27958             return mPermissionManager.getPermissionGids(permissionName, userId);
27959         }
27960 
27961         @Override
27962         public boolean isOnlyCoreApps() {
27963             return PackageManagerService.this.isOnlyCoreApps();
27964         }
27965 
27966         @Override
27967         public void freeStorage(String volumeUuid, long bytes, int storageFlags)
27968                 throws IOException {
27969             PackageManagerService.this.freeStorage(volumeUuid, bytes, storageFlags);
27970         }
27971 
27972         @Override
27973         public void forEachPackage(Consumer<AndroidPackage> actionLocked) {
27974             PackageManagerService.this.forEachPackage(actionLocked);
27975         }
27976 
27977         @Override
27978         public void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
27979             synchronized (mLock) {
27980                 for (int index = 0; index < mSettings.getPackagesLocked().size(); index++) {
27981                     actionLocked.accept(mSettings.getPackagesLocked().valueAt(index));
27982                 }
27983             }
27984         }
27985 
27986         @Override
27987         public void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
27988                 @UserIdInt int userId) {
27989             PackageManagerService.this.forEachInstalledPackage(actionLocked, userId);
27990         }
27991 
27992         @Override
27993         public ArraySet<String> getEnabledComponents(String packageName, int userId) {
27994             synchronized (mLock) {
27995                 PackageSetting setting = mSettings.getPackageLPr(packageName);
27996                 if (setting == null) {
27997                     return new ArraySet<>();
27998                 }
27999                 return setting.getEnabledComponents(userId);
28000             }
28001         }
28002 
28003         @Override
28004         public ArraySet<String> getDisabledComponents(String packageName, int userId) {
28005             synchronized (mLock) {
28006                 PackageSetting setting = mSettings.getPackageLPr(packageName);
28007                 if (setting == null) {
28008                     return new ArraySet<>();
28009                 }
28010                 return setting.getDisabledComponents(userId);
28011             }
28012         }
28013 
28014         @Override
28015         public @PackageManager.EnabledState int getApplicationEnabledState(
28016                 String packageName, int userId) {
28017             synchronized (mLock) {
28018                 PackageSetting setting = mSettings.getPackageLPr(packageName);
28019                 if (setting == null) {
28020                     return COMPONENT_ENABLED_STATE_DEFAULT;
28021                 }
28022                 return setting.getEnabled(userId);
28023             }
28024         }
28025 
28026         @Override
28027         public @PackageManager.EnabledState int getComponentEnabledSetting(
28028                 @NonNull ComponentName componentName, int callingUid, int userId) {
28029             return PackageManagerService.this.getComponentEnabledSettingInternal(componentName,
28030                     callingUid, userId);
28031         }
28032 
28033         @Override
28034         public void setEnableRollbackCode(int token, int enableRollbackCode) {
28035             PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
28036         }
28037 
28038         /**
28039          * Ask the package manager to compile layouts in the given package.
28040          */
28041         @Override
28042         public boolean compileLayouts(String packageName) {
28043             AndroidPackage pkg;
28044             synchronized (mLock) {
28045                 pkg = mPackages.get(packageName);
28046                 if (pkg == null) {
28047                     return false;
28048                 }
28049             }
28050             return mArtManagerService.compileLayouts(pkg);
28051         }
28052 
28053         @Override
28054         public void finishPackageInstall(int token, boolean didLaunch) {
28055             PackageManagerService.this.finishPackageInstall(token, didLaunch);
28056         }
28057 
28058         @Nullable
28059         @Override
28060         public String removeLegacyDefaultBrowserPackageName(int userId) {
28061             synchronized (mLock) {
28062                 return mSettings.removeDefaultBrowserPackageNameLPw(userId);
28063             }
28064         }
28065 
28066         @Override
28067         public boolean isApexPackage(String packageName) {
28068             return PackageManagerService.this.mApexManager.isApexPackage(packageName);
28069         }
28070 
28071         @Override
28072         public List<String> getApksInApex(String apexPackageName) {
28073             return PackageManagerService.this.mApexManager.getApksInApex(apexPackageName);
28074         }
28075 
28076         @Override
28077         public void uninstallApex(String packageName, long versionCode, int userId,
28078                 IntentSender intentSender, int flags) {
28079             final int callerUid = Binder.getCallingUid();
28080             if (callerUid != Process.ROOT_UID && callerUid != Process.SHELL_UID) {
28081                 throw new SecurityException("Not allowed to uninstall apexes");
28082             }
28083             PackageInstallerService.PackageDeleteObserverAdapter adapter =
28084                     new PackageInstallerService.PackageDeleteObserverAdapter(
28085                             PackageManagerService.this.mContext, intentSender, packageName,
28086                             false, userId);
28087             if ((flags & PackageManager.DELETE_ALL_USERS) == 0) {
28088                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
28089                         "Can't uninstall an apex for a single user");
28090                 return;
28091             }
28092             final ApexManager am = PackageManagerService.this.mApexManager;
28093             PackageInfo activePackage = am.getPackageInfo(packageName,
28094                     ApexManager.MATCH_ACTIVE_PACKAGE);
28095             if (activePackage == null) {
28096                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
28097                         packageName + " is not an apex package");
28098                 return;
28099             }
28100             if (versionCode != PackageManager.VERSION_CODE_HIGHEST
28101                     && activePackage.getLongVersionCode() != versionCode) {
28102                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
28103                         "Active version " + activePackage.getLongVersionCode()
28104                                 + " is not equal to " + versionCode + "]");
28105                 return;
28106             }
28107             if (!am.uninstallApex(activePackage.applicationInfo.sourceDir)) {
28108                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
28109                         "Failed to uninstall apex " + packageName);
28110             } else {
28111                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_SUCCEEDED,
28112                         null);
28113             }
28114         }
28115 
28116         @Override
28117         public void updateRuntimePermissionsFingerprint(@UserIdInt int userId) {
28118             synchronized (mLock) {
28119                 mSettings.updateRuntimePermissionsFingerprintLPr(userId);
28120             }
28121         }
28122 
28123         @Override
28124         public void migrateLegacyObbData() {
28125             try {
28126                 mInstaller.migrateLegacyObbData();
28127             } catch (Exception e) {
28128                 Slog.wtf(TAG, e);
28129             }
28130         }
28131 
28132         @Override
28133         public void writeSettings(boolean async) {
28134             synchronized (mLock) {
28135                 if (async) {
28136                     scheduleWriteSettingsLocked();
28137                 } else {
28138                     writeSettingsLPrTEMP();
28139                 }
28140             }
28141         }
28142 
28143         @Override
28144         public void writePermissionSettings(int[] userIds, boolean async) {
28145             synchronized (mLock) {
28146                 for (int userId : userIds) {
28147                     mSettings.writePermissionStateForUserLPr(userId, !async);
28148                 }
28149             }
28150         }
28151 
28152         @Override
28153         public boolean isCallerInstallerOfRecord(
28154                 @NonNull AndroidPackage pkg, int callingUid) {
28155             synchronized (mLock) {
28156                 if (pkg == null) {
28157                     return false;
28158                 }
28159                 final PackageSetting packageSetting = getPackageSetting(pkg.getPackageName());
28160                 if (packageSetting == null) {
28161                     return false;
28162                 }
28163                 final PackageSetting installerPackageSetting =
28164                         mSettings.getPackageLPr(packageSetting.installSource.installerPackageName);
28165                 return installerPackageSetting != null
28166                         && UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
28167             }
28168         }
28169 
28170         @Override
28171         public boolean isPermissionUpgradeNeeded(int userId) {
28172             synchronized (mLock) {
28173                 return mSettings.isPermissionUpgradeNeededLPr(userId);
28174             }
28175         }
28176 
28177         @Override
28178         public void setIntegrityVerificationResult(int verificationId, int verificationResult) {
28179             final Message msg = mHandler.obtainMessage(INTEGRITY_VERIFICATION_COMPLETE);
28180             msg.arg1 = verificationId;
28181             msg.obj = verificationResult;
28182             mHandler.sendMessage(msg);
28183         }
28184 
28185         @Override
28186         public List<String> getMimeGroup(String packageName, String mimeGroup) {
28187             return PackageManagerService.this.getMimeGroupInternal(packageName, mimeGroup);
28188         }
28189 
28190         @Override
28191         public void setVisibilityLogging(String packageName, boolean enable) {
28192             final PackageSetting pkg;
28193             synchronized (mLock) {
28194                 pkg = mSettings.getPackageLPr(packageName);
28195             }
28196             if (pkg == null) {
28197                 throw new IllegalStateException("No package found for " + packageName);
28198             }
28199             mAppsFilter.getFeatureConfig().enableLogging(pkg.appId, enable);
28200         }
28201 
28202         @Override
28203         public boolean isSystemPackage(@NonNull String packageName) {
28204             return packageName.equals(
28205                     PackageManagerService.this.ensureSystemPackageName(packageName));
28206         }
28207 
28208         @Override
28209         public void clearBlockUninstallForUser(@UserIdInt int userId) {
28210             synchronized (mLock) {
28211                 mSettings.clearBlockUninstallLPw(userId);
28212                 mSettings.writePackageRestrictionsLPr(userId);
28213             }
28214         }
28215 
28216         @Override
28217         public void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
28218             PackageManagerService.this.unsuspendForSuspendingPackage(packageName, affectedUser);
28219         }
28220 
28221         @Override
28222         public boolean isSuspendingAnyPackages(String suspendingPackage, int userId) {
28223             return PackageManagerService.this.isSuspendingAnyPackages(suspendingPackage, userId);
28224         }
28225 
28226         @Override
28227         public boolean registerInstalledLoadingProgressCallback(String packageName,
28228                 PackageManagerInternal.InstalledLoadingProgressCallback callback, int userId) {
28229             final PackageSetting ps = getPackageSettingForUser(packageName, Binder.getCallingUid(),
28230                     userId);
28231             if (ps == null) {
28232                 return false;
28233             }
28234             if (!ps.isPackageLoading()) {
28235                 Slog.w(TAG,
28236                         "Failed registering loading progress callback. Package is fully loaded.");
28237                 return false;
28238             }
28239             if (mIncrementalManager == null) {
28240                 Slog.w(TAG,
28241                         "Failed registering loading progress callback. Incremental is not enabled");
28242                 return false;
28243             }
28244             return mIncrementalManager.registerLoadingProgressCallback(ps.getPathString(),
28245                     (IPackageLoadingProgressCallback) callback.getBinder());
28246         }
28247 
28248         @Override
28249         public IncrementalStatesInfo getIncrementalStatesInfo(
28250                 @NonNull String packageName, int filterCallingUid, int userId) {
28251             final PackageSetting ps = getPackageSettingForUser(packageName, filterCallingUid,
28252                     userId);
28253             if (ps == null) {
28254                 return null;
28255             }
28256             return ps.getIncrementalStates();
28257         }
28258 
28259         @Override
28260         public void requestChecksums(@NonNull String packageName, boolean includeSplits,
28261                 @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
28262                 @Nullable List trustedInstallers,
28263                 @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
28264                 @NonNull Executor executor, @NonNull Handler handler) {
28265             requestChecksumsInternal(packageName, includeSplits, optional, required,
28266                     trustedInstallers, onChecksumsReadyListener, userId, executor, handler);
28267         }
28268 
28269         @Override
28270         public boolean isPackageFrozen(@NonNull String packageName,
28271                 int callingUid, int userId) {
28272             return PackageManagerService.this.getPackageStartability(
28273                     packageName, callingUid, userId) == PACKAGE_STARTABILITY_FROZEN;
28274         }
28275 
28276         @Override
28277         public long deleteOatArtifactsOfPackage(String packageName) {
28278             return PackageManagerService.this.deleteOatArtifactsOfPackage(packageName);
28279         }
28280 
28281         @Override
28282         public void withPackageSettingsSnapshot(
28283                 @NonNull Consumer<Function<String, PackageSetting>> block) {
28284             final Computer snapshot = snapshotComputer();
28285 
28286             // This method needs to either lock or not lock consistently throughout the method,
28287             // so if the live computer is returned, force a wrapping sync block.
28288             if (snapshot == mLiveComputer) {
28289                 synchronized (mLock) {
28290                     block.accept(snapshot::getPackageSetting);
28291                 }
28292             } else {
28293                 block.accept(snapshot::getPackageSetting);
28294             }
28295         }
28296 
28297         @Override
28298         public <Output> Output withPackageSettingsSnapshotReturning(
28299                 @NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
28300                         block) {
28301             final Computer snapshot = snapshotComputer();
28302 
28303             // This method needs to either lock or not lock consistently throughout the method,
28304             // so if the live computer is returned, force a wrapping sync block.
28305             if (snapshot == mLiveComputer) {
28306                 synchronized (mLock) {
28307                     return block.apply(snapshot::getPackageSetting);
28308                 }
28309             } else {
28310                 return block.apply(snapshot::getPackageSetting);
28311             }
28312         }
28313 
28314         @Override
28315         public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
28316                 @NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>,
28317                         ExceptionType> block) throws ExceptionType {
28318             final Computer snapshot = snapshotComputer();
28319 
28320             // This method needs to either lock or not lock consistently throughout the method,
28321             // so if the live computer is returned, force a wrapping sync block.
28322             if (snapshot == mLiveComputer) {
28323                 synchronized (mLock) {
28324                     block.accept(snapshot::getPackageSetting);
28325                 }
28326             } else {
28327                 block.accept(snapshot::getPackageSetting);
28328             }
28329         }
28330 
28331         @Override
28332         public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
28333                 withPackageSettingsSnapshotThrowing2(
28334                         @NonNull FunctionalUtils.ThrowingChecked2Consumer<
28335                                 Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)
28336                 throws ExceptionOne, ExceptionTwo {
28337             final Computer snapshot = snapshotComputer();
28338 
28339             // This method needs to either lock or not lock consistently throughout the method,
28340             // so if the live computer is returned, force a wrapping sync block.
28341             if (snapshot == mLiveComputer) {
28342                 synchronized (mLock) {
28343                     block.accept(snapshot::getPackageSetting);
28344                 }
28345             } else {
28346                 block.accept(snapshot::getPackageSetting);
28347             }
28348         }
28349 
28350         @Override
28351         public <Output, ExceptionType extends Exception> Output
28352                 withPackageSettingsSnapshotReturningThrowing(
28353                         @NonNull FunctionalUtils.ThrowingCheckedFunction<
28354                                 Function<String, PackageSetting>, Output, ExceptionType> block)
28355                 throws ExceptionType {
28356             final Computer snapshot = snapshotComputer();
28357 
28358             // This method needs to either lock or not lock consistently throughout the method,
28359             // so if the live computer is returned, force a wrapping sync block.
28360             if (snapshot == mLiveComputer) {
28361                 synchronized (mLock) {
28362                     return block.apply(snapshot::getPackageSetting);
28363                 }
28364             } else {
28365                 return block.apply(snapshot::getPackageSetting);
28366             }
28367         }
28368     }
28369 
28370     @GuardedBy("mLock")
28371     private SparseArray<String> getAppsWithSharedUserIdsLocked() {
28372         final SparseArray<String> sharedUserIds = new SparseArray<>();
28373         synchronized (mLock) {
28374             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
28375                 sharedUserIds.put(UserHandle.getAppId(setting.userId), setting.name);
28376             }
28377         }
28378         return sharedUserIds;
28379     }
28380 
28381     @GuardedBy("mLock")
28382     @NonNull
28383     private String[] getSharedUserPackagesForPackageLocked(String packageName, int userId) {
28384         final PackageSetting packageSetting = mSettings.getPackageLPr(packageName);
28385         if (packageSetting == null || !packageSetting.isSharedUser()) {
28386             return EmptyArray.STRING;
28387         }
28388 
28389         ArraySet<PackageSetting> packages = packageSetting.sharedUser.packages;
28390         final int numPackages = packages.size();
28391         String[] res = new String[numPackages];
28392         int i = 0;
28393         for (int index = 0; index < numPackages; index++) {
28394             final PackageSetting ps = packages.valueAt(index);
28395             if (ps.getInstalled(userId)) {
28396                 res[i++] = ps.name;
28397             }
28398         }
28399         res = ArrayUtils.trimToSize(res, i);
28400         return res != null ? res : EmptyArray.STRING;
28401     }
28402 
28403     @GuardedBy("mLock")
28404     public ArrayMap<String, ProcessInfo> getProcessesForUidLocked(int uid) {
28405         final int appId = UserHandle.getAppId(uid);
28406         final SettingBase obj = mSettings.getSettingLPr(appId);
28407         if (obj instanceof SharedUserSetting) {
28408             final SharedUserSetting sus = (SharedUserSetting) obj;
28409             return PackageInfoUtils.generateProcessInfo(sus.processes, 0);
28410         } else if (obj instanceof PackageSetting) {
28411             final PackageSetting ps = (PackageSetting) obj;
28412             return PackageInfoUtils.generateProcessInfo(ps.pkg.getProcesses(), 0);
28413         }
28414         return null;
28415     }
28416 
28417     @Override
28418     public int getRuntimePermissionsVersion(@UserIdInt int userId) {
28419         Preconditions.checkArgumentNonnegative(userId);
28420         enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
28421                 "getRuntimePermissionVersion");
28422         synchronized (mLock) {
28423             return mSettings.getDefaultRuntimePermissionsVersionLPr(userId);
28424         }
28425     }
28426 
28427     @Override
28428     public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
28429         Preconditions.checkArgumentNonnegative(version);
28430         Preconditions.checkArgumentNonnegative(userId);
28431         enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
28432                 "setRuntimePermissionVersion");
28433         synchronized (mLock) {
28434             mSettings.setDefaultRuntimePermissionsVersionLPr(version, userId);
28435         }
28436     }
28437 
28438     private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
28439             @NonNull String message) {
28440         if (mContext.checkCallingOrSelfPermission(
28441                 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
28442                 != PackageManager.PERMISSION_GRANTED
28443                 && mContext.checkCallingOrSelfPermission(
28444                 Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS)
28445                 != PackageManager.PERMISSION_GRANTED) {
28446             throw new SecurityException(message + " requires "
28447                     + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " or "
28448                     + Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS);
28449         }
28450     }
28451 
28452     @Nullable
28453     public PackageSetting getPackageSetting(String packageName) {
28454         return mComputer.getPackageSetting(packageName);
28455     }
28456 
28457     private PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
28458         return mComputer.getPackageSettingInternal(packageName, callingUid);
28459     }
28460 
28461     void forEachPackage(Consumer<AndroidPackage> actionLocked) {
28462         synchronized (mLock) {
28463             int numPackages = mPackages.size();
28464             for (int i = 0; i < numPackages; i++) {
28465                 actionLocked.accept(mPackages.valueAt(i));
28466             }
28467         }
28468     }
28469 
28470     void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
28471             @UserIdInt int userId) {
28472         synchronized (mLock) {
28473             int numPackages = mPackages.size();
28474             for (int i = 0; i < numPackages; i++) {
28475                 AndroidPackage pkg = mPackages.valueAt(i);
28476                 PackageSetting setting = mSettings.getPackageLPr(pkg.getPackageName());
28477                 if (setting == null || !setting.getInstalled(userId)) {
28478                     continue;
28479                 }
28480                 actionLocked.accept(pkg);
28481             }
28482         }
28483     }
28484 
28485     boolean isHistoricalPackageUsageAvailable() {
28486         synchronized (mLock) {
28487             return mPackageUsage.isHistoricalPackageUsageAvailable();
28488         }
28489     }
28490 
28491     /**
28492      * Return a <b>copy</b> of the collection of packages known to the package manager.
28493      * @return A copy of the values of mPackages.
28494      */
28495     Collection<AndroidPackage> getPackages() {
28496         synchronized (mLock) {
28497             return new ArrayList<>(mPackages.values());
28498         }
28499     }
28500 
28501     /**
28502      * Logs process start information (including base APK hash) to the security log.
28503      * @hide
28504      */
28505     @Override
28506     public void logAppProcessStartIfNeeded(String packageName, String processName, int uid,
28507             String seinfo, String apkFile, int pid) {
28508         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
28509             return;
28510         }
28511         if (!SecurityLog.isLoggingEnabled()) {
28512             return;
28513         }
28514         mProcessLoggingHandler.logAppProcessStart(mContext, mPmInternal, apkFile, packageName,
28515                 processName, uid, seinfo, pid);
28516     }
28517 
28518     public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
28519         return mCompilerStats.getPackageStats(pkgName);
28520     }
28521 
28522     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) {
28523         return getOrCreateCompilerPackageStats(pkg.getPackageName());
28524     }
28525 
28526     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
28527         return mCompilerStats.getOrCreatePackageStats(pkgName);
28528     }
28529 
28530     public void deleteCompilerPackageStats(String pkgName) {
28531         mCompilerStats.deletePackageStats(pkgName);
28532     }
28533 
28534     @Override
28535     public boolean isAutoRevokeWhitelisted(String packageName) {
28536         int mode = mInjector.getSystemService(AppOpsManager.class).checkOpNoThrow(
28537                 AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
28538                 Binder.getCallingUid(), packageName);
28539         return mode == MODE_IGNORED;
28540     }
28541 
28542     @Override
28543     public int getInstallReason(String packageName, int userId) {
28544         final int callingUid = Binder.getCallingUid();
28545         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
28546                 false /* checkShell */, "get install reason");
28547         synchronized (mLock) {
28548             final PackageSetting ps = mSettings.getPackageLPr(packageName);
28549             if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
28550                 return PackageManager.INSTALL_REASON_UNKNOWN;
28551             }
28552             if (ps != null) {
28553                 return ps.getInstallReason(userId);
28554             }
28555         }
28556         return PackageManager.INSTALL_REASON_UNKNOWN;
28557     }
28558 
28559     @Override
28560     public boolean canRequestPackageInstalls(String packageName, int userId) {
28561         return canRequestPackageInstallsInternal(packageName, Binder.getCallingUid(), userId,
28562                 true /* throwIfPermNotDeclared*/);
28563     }
28564 
28565     private boolean canRequestPackageInstallsInternal(String packageName, int callingUid,
28566             int userId, boolean throwIfPermNotDeclared) {
28567         int uid = getPackageUidInternal(packageName, 0, userId, callingUid);
28568         if (callingUid != uid && callingUid != Process.ROOT_UID
28569                 && callingUid != Process.SYSTEM_UID) {
28570             throw new SecurityException(
28571                     "Caller uid " + callingUid + " does not own package " + packageName);
28572         }
28573         if (isInstantAppInternal(packageName, userId, callingUid)) {
28574             return false;
28575         }
28576         final AndroidPackage pkg;
28577         synchronized (mLock) {
28578             pkg = mPackages.get(packageName);
28579         }
28580         if (pkg == null) {
28581             return false;
28582         }
28583         if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
28584             return false;
28585         }
28586         if (!pkg.getRequestedPermissions().contains(
28587                 android.Manifest.permission.REQUEST_INSTALL_PACKAGES)) {
28588             final String message = "Need to declare "
28589                     + android.Manifest.permission.REQUEST_INSTALL_PACKAGES
28590                     + " to call this api";
28591             if (throwIfPermNotDeclared) {
28592                 throw new SecurityException(message);
28593             } else {
28594                 Slog.e(TAG, message);
28595                 return false;
28596             }
28597         }
28598 
28599         return !isInstallDisabledForPackage(packageName, uid, userId);
28600     }
28601 
28602     /**
28603      * Returns true if the system or user is explicitly preventing an otherwise valid installer to
28604      * complete an install. This includes checks like unknown sources and user restrictions.
28605      */
28606     public boolean isInstallDisabledForPackage(String packageName, int uid, int userId) {
28607         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
28608                 || mUserManager.hasUserRestriction(
28609                 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
28610             return true;
28611         }
28612         if (mExternalSourcesPolicy != null) {
28613             int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
28614             return isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
28615         }
28616         return false;
28617     }
28618 
28619     @Override
28620     public ComponentName getInstantAppResolverSettingsComponent() {
28621         return mInstantAppResolverSettingsComponent;
28622     }
28623 
28624     @Override
28625     public ComponentName getInstantAppInstallerComponent() {
28626         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
28627             return null;
28628         }
28629         return mInstantAppInstallerActivity == null
28630                 ? null : mInstantAppInstallerActivity.getComponentName();
28631     }
28632 
28633     @Override
28634     public String getInstantAppAndroidId(String packageName, int userId) {
28635         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
28636                 "getInstantAppAndroidId");
28637         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
28638                 false /* checkShell */, "getInstantAppAndroidId");
28639         // Make sure the target is an Instant App.
28640         if (!isInstantApp(packageName, userId)) {
28641             return null;
28642         }
28643         synchronized (mLock) {
28644             return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
28645         }
28646     }
28647 
28648     @Override
28649     public void grantImplicitAccess(int recipientUid, String visibleAuthority) {
28650         // This API is exposed temporarily to only the contacts provider. (b/158688602)
28651         final int callingUid = Binder.getCallingUid();
28652         ProviderInfo contactsProvider = resolveContentProviderInternal(
28653                         ContactsContract.AUTHORITY, 0, UserHandle.getUserId(callingUid));
28654         if (contactsProvider == null || contactsProvider.applicationInfo == null
28655                 || !UserHandle.isSameApp(contactsProvider.applicationInfo.uid, callingUid)) {
28656             throw new SecurityException(callingUid + " is not allow to call grantImplicitAccess");
28657         }
28658         final int userId = UserHandle.getUserId(recipientUid);
28659         final long token = Binder.clearCallingIdentity();
28660         final ProviderInfo providerInfo;
28661         try {
28662             providerInfo = resolveContentProvider(visibleAuthority, 0 /*flags*/, userId);
28663         } finally {
28664             Binder.restoreCallingIdentity(token);
28665         }
28666         if (providerInfo == null) {
28667             return;
28668         }
28669         int visibleUid = providerInfo.applicationInfo.uid;
28670         mPmInternal.grantImplicitAccess(userId, null /*Intent*/, UserHandle.getAppId(recipientUid),
28671                 visibleUid, false);
28672     }
28673 
28674     boolean canHaveOatDir(String packageName) {
28675         synchronized (mLock) {
28676             AndroidPackage p = mPackages.get(packageName);
28677             PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
28678             if (p == null || pkgSetting == null) {
28679                 return false;
28680             }
28681             return AndroidPackageUtils.canHaveOatDir(p,
28682                     pkgSetting.getPkgState().isUpdatedSystemApp());
28683         }
28684     }
28685 
28686     long deleteOatArtifactsOfPackage(String packageName) {
28687         final AndroidPackage pkg;
28688         final PackageSetting pkgSetting;
28689         synchronized (mLock) {
28690             pkg = mPackages.get(packageName);
28691             pkgSetting = mSettings.getPackageLPr(packageName);
28692         }
28693         return mDexManager.deleteOptimizedFiles(ArtUtils.createArtPackageInfo(pkg, pkgSetting));
28694     }
28695 
28696     Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
28697         Set<String> unusedPackages = new HashSet<>();
28698         long currentTimeInMillis = System.currentTimeMillis();
28699         synchronized (mLock) {
28700             for (AndroidPackage pkg : mPackages.values()) {
28701                 PackageSetting ps =  mSettings.getPackageLPr(pkg.getPackageName());
28702                 if (ps == null) {
28703                     continue;
28704                 }
28705                 PackageDexUsage.PackageUseInfo packageUseInfo =
28706                       getDexManager().getPackageUseInfoOrDefault(pkg.getPackageName());
28707                 if (PackageManagerServiceUtils
28708                         .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
28709                                 downgradeTimeThresholdMillis, packageUseInfo,
28710                                 ps.getPkgState().getLatestPackageUseTimeInMills(),
28711                                 ps.getPkgState().getLatestForegroundPackageUseTimeInMills())) {
28712                     unusedPackages.add(pkg.getPackageName());
28713                 }
28714             }
28715         }
28716         return unusedPackages;
28717     }
28718 
28719     @Override
28720     public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
28721             int userId) {
28722         final int callingUid = Binder.getCallingUid();
28723         final int callingAppId = UserHandle.getAppId(callingUid);
28724 
28725         enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
28726                 true /*checkShell*/, "setHarmfulAppInfo");
28727 
28728         if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
28729                 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
28730             throw new SecurityException("Caller must have the "
28731                     + SET_HARMFUL_APP_WARNINGS + " permission.");
28732         }
28733 
28734         synchronized (mLock) {
28735             mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
28736             scheduleWritePackageRestrictionsLocked(userId);
28737         }
28738     }
28739 
28740     @Nullable
28741     @Override
28742     public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
28743         final int callingUid = Binder.getCallingUid();
28744         final int callingAppId = UserHandle.getAppId(callingUid);
28745 
28746         enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
28747                 true /*checkShell*/, "getHarmfulAppInfo");
28748 
28749         if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
28750                 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
28751             throw new SecurityException("Caller must have the "
28752                     + SET_HARMFUL_APP_WARNINGS + " permission.");
28753         }
28754 
28755         synchronized (mLock) {
28756             return mSettings.getHarmfulAppWarningLPr(packageName, userId);
28757         }
28758     }
28759 
28760     @Override
28761     public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
28762         final int callingUid = Binder.getCallingUid();
28763         final int callingAppId = UserHandle.getAppId(callingUid);
28764 
28765         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
28766                 true /*checkShell*/, "isPackageStateProtected");
28767 
28768         if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
28769                 && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
28770             throw new SecurityException("Caller must have the "
28771                     + MANAGE_DEVICE_ADMINS + " permission.");
28772         }
28773 
28774         return mProtectedPackages.isPackageStateProtected(userId, packageName);
28775     }
28776 
28777     @Override
28778     public void sendDeviceCustomizationReadyBroadcast() {
28779         mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
28780                 "sendDeviceCustomizationReadyBroadcast");
28781 
28782         final long ident = Binder.clearCallingIdentity();
28783         try {
28784             final Intent intent = new Intent(Intent.ACTION_DEVICE_CUSTOMIZATION_READY);
28785             intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
28786             final IActivityManager am = ActivityManager.getService();
28787             final String[] requiredPermissions = {
28788                 Manifest.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY,
28789             };
28790             try {
28791                 am.broadcastIntentWithFeature(null, null, intent, null, null, 0, null, null,
28792                         requiredPermissions, null, android.app.AppOpsManager.OP_NONE, null, false,
28793                         false, UserHandle.USER_ALL);
28794             } catch (RemoteException e) {
28795                 throw e.rethrowFromSystemServer();
28796             }
28797         } finally {
28798             Binder.restoreCallingIdentity(ident);
28799         }
28800     }
28801 
28802     private void applyMimeGroupChanges(String packageName, String mimeGroup) {
28803         if (mComponentResolver.updateMimeGroup(packageName, mimeGroup)) {
28804             Binder.withCleanCallingIdentity(() ->
28805                     clearPackagePreferredActivities(packageName, UserHandle.USER_ALL));
28806         }
28807 
28808         mPmInternal.writeSettings(false);
28809     }
28810 
28811     @Override
28812     public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
28813         enforceOwnerRights(packageName, Binder.getCallingUid());
28814         final boolean changed;
28815         synchronized (mLock) {
28816             changed = mSettings.getPackageLPr(packageName).setMimeGroup(mimeGroup, mimeTypes);
28817         }
28818         if (changed) {
28819             applyMimeGroupChanges(packageName, mimeGroup);
28820         }
28821     }
28822 
28823     @Override
28824     public List<String> getMimeGroup(String packageName, String mimeGroup) {
28825         enforceOwnerRights(packageName, Binder.getCallingUid());
28826         return getMimeGroupInternal(packageName, mimeGroup);
28827     }
28828 
28829     private List<String> getMimeGroupInternal(String packageName, String mimeGroup) {
28830         synchronized (mLock) {
28831             return mSettings.getPackageLPr(packageName).getMimeGroup(mimeGroup);
28832         }
28833     }
28834 
28835     @Override
28836     public void setSplashScreenTheme(@NonNull String packageName, @Nullable String themeId,
28837             int userId) {
28838         final int callingUid = Binder.getCallingUid();
28839         enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
28840                 false /* checkShell */, "setSplashScreenTheme");
28841         enforceOwnerRights(packageName, callingUid);
28842         final PackageSetting packageSetting = getPackageSettingForUser(packageName, callingUid,
28843                 userId);
28844         if (packageSetting != null) {
28845             packageSetting.setSplashScreenTheme(userId, themeId);
28846         }
28847     }
28848 
28849     @Override
28850     public String getSplashScreenTheme(@NonNull String packageName, int userId) {
28851         int callingUid = Binder.getCallingUid();
28852         PackageSetting packageSetting = getPackageSettingForUser(packageName, callingUid, userId);
28853         return packageSetting != null ? packageSetting.getSplashScreenTheme(userId) : null;
28854     }
28855 
28856     /**
28857      * Temporary method that wraps mSettings.writeLPr() and calls mPermissionManager's
28858      * writeLegacyPermissionsTEMP() beforehand.
28859      *
28860      * TODO(zhanghai): This should be removed once we finish migration of permission storage.
28861      */
28862     private void writeSettingsLPrTEMP() {
28863         mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions);
28864         mSettings.writeLPr();
28865     }
28866 
28867     @Override
28868     public IBinder getHoldLockToken() {
28869         if (!Build.IS_DEBUGGABLE) {
28870             throw new SecurityException("getHoldLockToken requires a debuggable build");
28871         }
28872 
28873         mContext.enforceCallingPermission(
28874                 Manifest.permission.INJECT_EVENTS,
28875                 "getHoldLockToken requires INJECT_EVENTS permission");
28876 
28877         final Binder token = new Binder();
28878         token.attachInterface(this, "holdLock:" + Binder.getCallingUid());
28879         return token;
28880     }
28881 
28882     @Override
28883     public void verifyHoldLockToken(IBinder token) {
28884         if (!Build.IS_DEBUGGABLE) {
28885             throw new SecurityException("holdLock requires a debuggable build");
28886         }
28887 
28888         if (token == null) {
28889             throw new SecurityException("null holdLockToken");
28890         }
28891 
28892         if (token.queryLocalInterface("holdLock:" + Binder.getCallingUid()) != this) {
28893             throw new SecurityException("Invalid holdLock() token");
28894         }
28895     }
28896 
28897     @Override
28898     public void holdLock(IBinder token, int durationMs) {
28899         mTestUtilityService.verifyHoldLockToken(token);
28900 
28901         synchronized (mLock) {
28902             SystemClock.sleep(durationMs);
28903         }
28904     }
28905 
28906     private static String getDefaultTimeouts() {
28907         final long token = Binder.clearCallingIdentity();
28908         try {
28909             return DeviceConfig.getString(NAMESPACE_PACKAGE_MANAGER_SERVICE,
28910                     PROPERTY_INCFS_DEFAULT_TIMEOUTS, "");
28911         } finally {
28912             Binder.restoreCallingIdentity(token);
28913         }
28914     }
28915 
28916     private static String getKnownDigestersList() {
28917         final long token = Binder.clearCallingIdentity();
28918         try {
28919             return DeviceConfig.getString(NAMESPACE_PACKAGE_MANAGER_SERVICE,
28920                     PROPERTY_KNOWN_DIGESTERS_LIST, "");
28921         } finally {
28922             Binder.restoreCallingIdentity(token);
28923         }
28924     }
28925 
28926     /**
28927      * Returns the array containing per-uid timeout configuration.
28928      * This is derived from DeviceConfig flags.
28929      */
28930     public @NonNull PerUidReadTimeouts[] getPerUidReadTimeouts() {
28931         PerUidReadTimeouts[] result = mPerUidReadTimeoutsCache;
28932         if (result == null) {
28933             result = parsePerUidReadTimeouts();
28934             mPerUidReadTimeoutsCache = result;
28935         }
28936         return result;
28937     }
28938 
28939     private @NonNull PerUidReadTimeouts[] parsePerUidReadTimeouts() {
28940         final String defaultTimeouts = getDefaultTimeouts();
28941         final String knownDigestersList = getKnownDigestersList();
28942         final List<PerPackageReadTimeouts> perPackageReadTimeouts =
28943                 PerPackageReadTimeouts.parseDigestersList(defaultTimeouts, knownDigestersList);
28944 
28945         if (perPackageReadTimeouts.size() == 0) {
28946             return EMPTY_PER_UID_READ_TIMEOUTS_ARRAY;
28947         }
28948 
28949         final int[] allUsers = mInjector.getUserManagerService().getUserIds();
28950 
28951         List<PerUidReadTimeouts> result = new ArrayList<>(perPackageReadTimeouts.size());
28952         synchronized (mLock) {
28953             for (int i = 0, size = perPackageReadTimeouts.size(); i < size; ++i) {
28954                 final PerPackageReadTimeouts perPackage = perPackageReadTimeouts.get(i);
28955                 final PackageSetting ps = mSettings.mPackages.get(perPackage.packageName);
28956                 if (ps == null) {
28957                     if (DEBUG_PER_UID_READ_TIMEOUTS) {
28958                         Slog.i(TAG, "PerUidReadTimeouts: package not found = "
28959                                 + perPackage.packageName);
28960                     }
28961                     continue;
28962                 }
28963                 if (ps.appId < Process.FIRST_APPLICATION_UID) {
28964                     if (DEBUG_PER_UID_READ_TIMEOUTS) {
28965                         Slog.i(TAG, "PerUidReadTimeouts: package is system, appId=" + ps.appId);
28966                     }
28967                     continue;
28968                 }
28969 
28970                 final AndroidPackage pkg = ps.getPkg();
28971                 if (pkg.getLongVersionCode() < perPackage.versionCodes.minVersionCode
28972                         || pkg.getLongVersionCode() > perPackage.versionCodes.maxVersionCode) {
28973                     if (DEBUG_PER_UID_READ_TIMEOUTS) {
28974                         Slog.i(TAG, "PerUidReadTimeouts: version code is not in range = "
28975                                 + perPackage.packageName + ":" + pkg.getLongVersionCode());
28976                     }
28977                     continue;
28978                 }
28979                 if (perPackage.sha256certificate != null
28980                         && !pkg.getSigningDetails().hasSha256Certificate(
28981                         perPackage.sha256certificate)) {
28982                     if (DEBUG_PER_UID_READ_TIMEOUTS) {
28983                         Slog.i(TAG, "PerUidReadTimeouts: invalid certificate = "
28984                                 + perPackage.packageName + ":" + pkg.getLongVersionCode());
28985                     }
28986                     continue;
28987                 }
28988                 for (int userId : allUsers) {
28989                     if (!ps.getInstalled(userId)) {
28990                         continue;
28991                     }
28992                     final int uid = UserHandle.getUid(userId, ps.appId);
28993                     final PerUidReadTimeouts perUid = new PerUidReadTimeouts();
28994                     perUid.uid = uid;
28995                     perUid.minTimeUs = perPackage.timeouts.minTimeUs;
28996                     perUid.minPendingTimeUs = perPackage.timeouts.minPendingTimeUs;
28997                     perUid.maxPendingTimeUs = perPackage.timeouts.maxPendingTimeUs;
28998                     result.add(perUid);
28999                 }
29000             }
29001         }
29002         return result.toArray(new PerUidReadTimeouts[result.size()]);
29003     }
29004 
29005     static @NonNull BroadcastOptions getTemporaryAppAllowlistBroadcastOptions(
29006             @PowerWhitelistManager.ReasonCode int reasonCode) {
29007         long duration = 10_000;
29008         final ActivityManagerInternal amInternal =
29009                 LocalServices.getService(ActivityManagerInternal.class);
29010         if (amInternal != null) {
29011             duration = amInternal.getBootTimeTempAllowListDuration();
29012         }
29013         final BroadcastOptions bOptions = BroadcastOptions.makeBasic();
29014         bOptions.setTemporaryAppAllowlist(duration,
29015                 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
29016                 reasonCode, "");
29017         return bOptions;
29018     }
29019 
29020     @NonNull
29021     public DomainVerificationService.Connection getDomainVerificationConnection() {
29022         return mDomainVerificationConnection;
29023     }
29024 
29025     @Override
29026     public void setKeepUninstalledPackages(List<String> packageList) {
29027         mContext.enforceCallingPermission(
29028                 Manifest.permission.KEEP_UNINSTALLED_PACKAGES,
29029                 "setKeepUninstalledPackages requires KEEP_UNINSTALLED_PACKAGES permission");
29030         Objects.requireNonNull(packageList);
29031 
29032         setKeepUninstalledPackagesInternal(packageList);
29033     }
29034 
29035     private void setKeepUninstalledPackagesInternal(List<String> packageList) {
29036         Preconditions.checkNotNull(packageList);
29037         List<String> removedFromList = null;
29038         synchronized (mLock) {
29039             if (mKeepUninstalledPackages != null) {
29040                 final int packagesCount = mKeepUninstalledPackages.size();
29041                 for (int i = 0; i < packagesCount; i++) {
29042                     String oldPackage = mKeepUninstalledPackages.get(i);
29043                     if (packageList != null && packageList.contains(oldPackage)) {
29044                         continue;
29045                     }
29046                     if (removedFromList == null) {
29047                         removedFromList = new ArrayList<>();
29048                     }
29049                     removedFromList.add(oldPackage);
29050                 }
29051             }
29052             mKeepUninstalledPackages = new ArrayList<>(packageList);
29053             if (removedFromList != null) {
29054                 final int removedCount = removedFromList.size();
29055                 for (int i = 0; i < removedCount; i++) {
29056                     deletePackageIfUnusedLPr(removedFromList.get(i));
29057                 }
29058             }
29059         }
29060     }
29061 
29062     private static class TempUserState {
29063         public final int enabledState;
29064         @Nullable
29065         public final String lastDisableAppCaller;
29066         public final boolean installed;
29067 
29068         private TempUserState(int enabledState, @Nullable String lastDisableAppCaller,
29069                 boolean installed) {
29070             this.enabledState = enabledState;
29071             this.lastDisableAppCaller = lastDisableAppCaller;
29072             this.installed = installed;
29073         }
29074     }
29075 }
29076 
29077 interface PackageSender {
29078     /**
29079      * @param userIds User IDs where the action occurred on a full application
29080      * @param instantUserIds User IDs where the action occurred on an instant application
29081      */
29082     void sendPackageBroadcast(final String action, final String pkg,
29083             final Bundle extras, final int flags, final String targetPkg,
29084             final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds,
29085             @Nullable SparseArray<int[]> broadcastAllowList, @Nullable Bundle bOptions);
29086     void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
29087             boolean includeStopped, int appId, int[] userIds, int[] instantUserIds,
29088             int dataLoaderType);
29089     void notifyPackageAdded(String packageName, int uid);
29090     void notifyPackageChanged(String packageName, int uid);
29091     void notifyPackageRemoved(String packageName, int uid);
29092 }
29093