• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.pm;
18 
19 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
21 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
22 import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_PERMISSION_GROUP;
23 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
24 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
25 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP;
26 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
27 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
28 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
29 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
30 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
31 import static android.content.pm.PackageManager.INSTALL_FAILED_SESSION_INVALID;
32 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
33 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
34 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
35 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
36 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
37 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
38 import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
39 import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
40 import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile;
41 import static android.os.PowerExemptionManager.REASON_PACKAGE_REPLACED;
42 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
43 import static android.os.incremental.IncrementalManager.isIncrementalPath;
44 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
45 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
46 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
47 
48 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
49 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
50 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
51 import static com.android.server.pm.PackageManagerService.DEBUG_BACKUP;
52 import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION;
53 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
54 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
55 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
56 import static com.android.server.pm.PackageManagerService.DEBUG_UPGRADE;
57 import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY;
58 import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY;
59 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
60 import static com.android.server.pm.PackageManagerService.POST_INSTALL;
61 import static com.android.server.pm.PackageManagerService.PRECOMPILE_LAYOUTS;
62 import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX;
63 import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP;
64 import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
65 import static com.android.server.pm.PackageManagerService.SCAN_AS_ODM;
66 import static com.android.server.pm.PackageManagerService.SCAN_AS_OEM;
67 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRIVILEGED;
68 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRODUCT;
69 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM;
70 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM_EXT;
71 import static com.android.server.pm.PackageManagerService.SCAN_AS_VENDOR;
72 import static com.android.server.pm.PackageManagerService.SCAN_AS_VIRTUAL_PRELOAD;
73 import static com.android.server.pm.PackageManagerService.SCAN_BOOTING;
74 import static com.android.server.pm.PackageManagerService.SCAN_DONT_KILL_APP;
75 import static com.android.server.pm.PackageManagerService.SCAN_DROP_CACHE;
76 import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE;
77 import static com.android.server.pm.PackageManagerService.SCAN_IGNORE_FROZEN;
78 import static com.android.server.pm.PackageManagerService.SCAN_INITIAL;
79 import static com.android.server.pm.PackageManagerService.SCAN_MOVE;
80 import static com.android.server.pm.PackageManagerService.SCAN_NEW_INSTALL;
81 import static com.android.server.pm.PackageManagerService.SCAN_NO_DEX;
82 import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN;
83 import static com.android.server.pm.PackageManagerService.SCAN_UPDATE_SIGNATURE;
84 import static com.android.server.pm.PackageManagerService.TAG;
85 import static com.android.server.pm.PackageManagerServiceUtils.comparePackageSignatures;
86 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
87 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
88 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
89 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
90 import static com.android.server.pm.SharedUidMigration.BEST_EFFORT;
91 
92 import android.annotation.NonNull;
93 import android.annotation.Nullable;
94 import android.annotation.UserIdInt;
95 import android.app.AppOpsManager;
96 import android.app.ApplicationPackageManager;
97 import android.app.BroadcastOptions;
98 import android.app.backup.IBackupManager;
99 import android.content.ContentResolver;
100 import android.content.Context;
101 import android.content.Intent;
102 import android.content.IntentSender;
103 import android.content.pm.ApplicationInfo;
104 import android.content.pm.DataLoaderType;
105 import android.content.pm.IPackageInstallObserver2;
106 import android.content.pm.PackageChangeEvent;
107 import android.content.pm.PackageInfo;
108 import android.content.pm.PackageInfoLite;
109 import android.content.pm.PackageInstaller;
110 import android.content.pm.PackageManager;
111 import android.content.pm.PermissionGroupInfo;
112 import android.content.pm.PermissionInfo;
113 import android.content.pm.SharedLibraryInfo;
114 import android.content.pm.Signature;
115 import android.content.pm.SigningDetails;
116 import android.content.pm.VerifierInfo;
117 import android.content.pm.dex.DexMetadataHelper;
118 import android.content.pm.parsing.result.ParseResult;
119 import android.content.pm.parsing.result.ParseTypeImpl;
120 import android.net.Uri;
121 import android.os.Binder;
122 import android.os.Build;
123 import android.os.Bundle;
124 import android.os.Environment;
125 import android.os.Message;
126 import android.os.Process;
127 import android.os.RemoteException;
128 import android.os.SystemProperties;
129 import android.os.Trace;
130 import android.os.UserHandle;
131 import android.os.UserManager;
132 import android.os.incremental.IncrementalManager;
133 import android.os.incremental.IncrementalStorage;
134 import android.os.storage.StorageManager;
135 import android.os.storage.VolumeInfo;
136 import android.stats.storage.StorageEnums;
137 import android.util.ArrayMap;
138 import android.util.ArraySet;
139 import android.util.EventLog;
140 import android.util.Log;
141 import android.util.Pair;
142 import android.util.Slog;
143 import android.util.SparseArray;
144 
145 import com.android.internal.annotations.GuardedBy;
146 import com.android.internal.content.F2fsUtils;
147 import com.android.internal.content.InstallLocationUtils;
148 import com.android.internal.security.VerityUtils;
149 import com.android.internal.util.ArrayUtils;
150 import com.android.internal.util.CollectionUtils;
151 import com.android.internal.util.FrameworkStatsLog;
152 import com.android.server.EventLogTags;
153 import com.android.server.pm.dex.ArtManagerService;
154 import com.android.server.pm.dex.DexManager;
155 import com.android.server.pm.dex.DexoptOptions;
156 import com.android.server.pm.dex.ViewCompiler;
157 import com.android.server.pm.parsing.PackageCacher;
158 import com.android.server.pm.parsing.PackageParser2;
159 import com.android.server.pm.parsing.pkg.AndroidPackage;
160 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
161 import com.android.server.pm.parsing.pkg.ParsedPackage;
162 import com.android.server.pm.permission.Permission;
163 import com.android.server.pm.permission.PermissionManagerServiceInternal;
164 import com.android.server.pm.pkg.PackageStateInternal;
165 import com.android.server.pm.pkg.component.ComponentMutateUtils;
166 import com.android.server.pm.pkg.component.ParsedInstrumentation;
167 import com.android.server.pm.pkg.component.ParsedPermission;
168 import com.android.server.pm.pkg.component.ParsedPermissionGroup;
169 import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
170 import com.android.server.rollback.RollbackManagerInternal;
171 import com.android.server.utils.WatchedArrayMap;
172 import com.android.server.utils.WatchedLongSparseArray;
173 
174 import dalvik.system.VMRuntime;
175 
176 import java.io.File;
177 import java.io.FileInputStream;
178 import java.io.IOException;
179 import java.security.DigestException;
180 import java.security.DigestInputStream;
181 import java.security.MessageDigest;
182 import java.security.NoSuchAlgorithmException;
183 import java.security.PublicKey;
184 import java.security.cert.CertificateException;
185 import java.util.ArrayList;
186 import java.util.Arrays;
187 import java.util.Collections;
188 import java.util.List;
189 import java.util.Map;
190 import java.util.Set;
191 import java.util.concurrent.ExecutorService;
192 
193 final class InstallPackageHelper {
194     private final PackageManagerService mPm;
195     private final AppDataHelper mAppDataHelper;
196     private final BroadcastHelper mBroadcastHelper;
197     private final RemovePackageHelper mRemovePackageHelper;
198     private final IncrementalManager mIncrementalManager;
199     private final ApexManager mApexManager;
200     private final DexManager mDexManager;
201     private final ArtManagerService mArtManagerService;
202     private final Context mContext;
203     private final PackageDexOptimizer mPackageDexOptimizer;
204     private final PackageAbiHelper mPackageAbiHelper;
205     private final ViewCompiler mViewCompiler;
206     private final SharedLibrariesImpl mSharedLibraries;
207     private final PackageManagerServiceInjector mInjector;
208 
209     // TODO(b/198166813): remove PMS dependency
InstallPackageHelper(PackageManagerService pm, AppDataHelper appDataHelper)210     InstallPackageHelper(PackageManagerService pm, AppDataHelper appDataHelper) {
211         mPm = pm;
212         mInjector = pm.mInjector;
213         mAppDataHelper = appDataHelper;
214         mBroadcastHelper = new BroadcastHelper(pm.mInjector);
215         mRemovePackageHelper = new RemovePackageHelper(pm);
216         mIncrementalManager = pm.mInjector.getIncrementalManager();
217         mApexManager = pm.mInjector.getApexManager();
218         mDexManager = pm.mInjector.getDexManager();
219         mArtManagerService = pm.mInjector.getArtManagerService();
220         mContext = pm.mInjector.getContext();
221         mPackageDexOptimizer = pm.mInjector.getPackageDexOptimizer();
222         mPackageAbiHelper = pm.mInjector.getAbiHelper();
223         mViewCompiler = pm.mInjector.getViewCompiler();
224         mSharedLibraries = pm.mInjector.getSharedLibrariesImpl();
225     }
226 
InstallPackageHelper(PackageManagerService pm)227     InstallPackageHelper(PackageManagerService pm) {
228         this(pm, new AppDataHelper(pm));
229     }
230 
231     /**
232      * Commits the package scan and modifies system state.
233      * <p><em>WARNING:</em> The method may throw an exception in the middle
234      * of committing the package, leaving the system in an inconsistent state.
235      * This needs to be fixed so, once we get to this point, no errors are
236      * possible and the system is not left in an inconsistent state.
237      */
238     @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
commitReconciledScanResultLocked( @onNull ReconciledPackage reconciledPkg, int[] allUsers)239     public AndroidPackage commitReconciledScanResultLocked(
240             @NonNull ReconciledPackage reconciledPkg, int[] allUsers) {
241         final ScanResult result = reconciledPkg.mScanResult;
242         final ScanRequest request = result.mRequest;
243         // TODO(b/135203078): Move this even further away
244         ParsedPackage parsedPackage = request.mParsedPackage;
245         if ("android".equals(parsedPackage.getPackageName())) {
246             // TODO(b/135203078): Move this to initial parse
247             parsedPackage.setVersionCode(mPm.getSdkVersion())
248                     .setVersionCodeMajor(0);
249         }
250 
251         final AndroidPackage oldPkg = request.mOldPkg;
252         final @ParsingPackageUtils.ParseFlags int parseFlags = request.mParseFlags;
253         final @PackageManagerService.ScanFlags int scanFlags = request.mScanFlags;
254         final PackageSetting oldPkgSetting = request.mOldPkgSetting;
255         final PackageSetting originalPkgSetting = request.mOriginalPkgSetting;
256         final UserHandle user = request.mUser;
257         final String realPkgName = request.mRealPkgName;
258         final List<String> changedAbiCodePath = result.mChangedAbiCodePath;
259         final PackageSetting pkgSetting;
260         if (request.mPkgSetting != null) {
261             SharedUserSetting requestSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(
262                     request.mPkgSetting);
263             SharedUserSetting resultSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(
264                     result.mPkgSetting);
265             if (requestSharedUserSetting != null
266                     && requestSharedUserSetting != resultSharedUserSetting) {
267                 // shared user changed, remove from old shared user
268                 requestSharedUserSetting.removePackage(request.mPkgSetting);
269                 // Prune unused SharedUserSetting
270                 if (mPm.mSettings.checkAndPruneSharedUserLPw(requestSharedUserSetting, false)) {
271                     // Set the app ID in removed info for UID_REMOVED broadcasts
272                     if (reconciledPkg.mInstallResult != null
273                             && reconciledPkg.mInstallResult.mRemovedInfo != null) {
274                         reconciledPkg.mInstallResult.mRemovedInfo.mRemovedAppId =
275                                 requestSharedUserSetting.mAppId;
276                     }
277                 }
278             }
279         }
280         if (result.mExistingSettingCopied) {
281             pkgSetting = request.mPkgSetting;
282             pkgSetting.updateFrom(result.mPkgSetting);
283         } else {
284             pkgSetting = result.mPkgSetting;
285             if (originalPkgSetting != null) {
286                 mPm.mSettings.addRenamedPackageLPw(
287                         AndroidPackageUtils.getRealPackageOrNull(parsedPackage),
288                         originalPkgSetting.getPackageName());
289                 mPm.mTransferredPackages.add(originalPkgSetting.getPackageName());
290             } else {
291                 mPm.mSettings.removeRenamedPackageLPw(parsedPackage.getPackageName());
292             }
293         }
294         SharedUserSetting sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(pkgSetting);
295         if (sharedUserSetting != null) {
296             sharedUserSetting.addPackage(pkgSetting);
297             if (parsedPackage.isLeavingSharedUid()
298                     && SharedUidMigration.applyStrategy(BEST_EFFORT)
299                     && sharedUserSetting.isSingleUser()) {
300                 // Attempt the transparent shared UID migration
301                 mPm.mSettings.convertSharedUserSettingsLPw(sharedUserSetting);
302             }
303         }
304         if (reconciledPkg.mInstallArgs != null
305                 && reconciledPkg.mInstallArgs.mForceQueryableOverride) {
306             pkgSetting.setForceQueryableOverride(true);
307         }
308 
309         // If this is part of a standard install, set the initiating package name, else rely on
310         // previous device state.
311         if (reconciledPkg.mInstallArgs != null) {
312             InstallSource installSource = reconciledPkg.mInstallArgs.mInstallSource;
313             if (installSource.initiatingPackageName != null) {
314                 final PackageSetting ips = mPm.mSettings.getPackageLPr(
315                         installSource.initiatingPackageName);
316                 if (ips != null) {
317                     installSource = installSource.setInitiatingPackageSignatures(
318                             ips.getSignatures());
319                 }
320             }
321             pkgSetting.setInstallSource(installSource);
322         }
323 
324         // TODO(toddke): Consider a method specifically for modifying the Package object
325         // post scan; or, moving this stuff out of the Package object since it has nothing
326         // to do with the package on disk.
327         // We need to have this here because addUserToSettingLPw() is sometimes responsible
328         // for creating the application ID. If we did this earlier, we would be saving the
329         // correct ID.
330         parsedPackage.setUid(pkgSetting.getAppId());
331         final AndroidPackage pkg = parsedPackage.hideAsFinal();
332 
333         mPm.mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
334 
335         if (realPkgName != null) {
336             mPm.mTransferredPackages.add(pkg.getPackageName());
337         }
338 
339         if (reconciledPkg.mCollectedSharedLibraryInfos != null
340                 || (oldPkgSetting != null && oldPkgSetting.getUsesLibraryInfos() != null)) {
341             // Reconcile if the new package or the old package uses shared libraries.
342             // It is possible that the old package uses shared libraries but the new one doesn't.
343             mSharedLibraries.executeSharedLibrariesUpdateLPw(pkg, pkgSetting, null, null,
344                     reconciledPkg.mCollectedSharedLibraryInfos, allUsers);
345         }
346 
347         final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
348         if (reconciledPkg.mRemoveAppKeySetData) {
349             ksms.removeAppKeySetDataLPw(pkg.getPackageName());
350         }
351         if (reconciledPkg.mSharedUserSignaturesChanged) {
352             sharedUserSetting.signaturesChanged = Boolean.TRUE;
353             sharedUserSetting.signatures.mSigningDetails = reconciledPkg.mSigningDetails;
354         }
355         pkgSetting.setSigningDetails(reconciledPkg.mSigningDetails);
356 
357         if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
358             for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
359                 final String codePathString = changedAbiCodePath.get(i);
360                 try {
361                     mPm.mInstaller.rmdex(codePathString,
362                             getDexCodeInstructionSet(getPreferredInstructionSet()));
363                 } catch (Installer.InstallerException ignored) {
364                 }
365             }
366         }
367 
368         final int userId = user == null ? 0 : user.getIdentifier();
369         // Modify state for the given package setting
370         commitPackageSettings(pkg, oldPkg, pkgSetting, oldPkgSetting, scanFlags,
371                 (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
372         if (pkgSetting.getInstantApp(userId)) {
373             mPm.mInstantAppRegistry.addInstantApp(userId, pkgSetting.getAppId());
374         }
375 
376         if (!IncrementalManager.isIncrementalPath(pkgSetting.getPathString())) {
377             pkgSetting.setLoadingProgress(1f);
378         }
379 
380         return pkg;
381     }
382 
383     /**
384      * Adds a scanned package to the system. When this method is finished, the package will
385      * be available for query, resolution, etc...
386      */
commitPackageSettings(@onNull AndroidPackage pkg, @Nullable AndroidPackage oldPkg, @NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting, final @PackageManagerService.ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg)387     private void commitPackageSettings(@NonNull AndroidPackage pkg, @Nullable AndroidPackage oldPkg,
388             @NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting,
389             final @PackageManagerService.ScanFlags int scanFlags, boolean chatty,
390             ReconciledPackage reconciledPkg) {
391         final String pkgName = pkg.getPackageName();
392         if (mPm.mCustomResolverComponentName != null
393                 && mPm.mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) {
394             mPm.setUpCustomResolverActivity(pkg, pkgSetting);
395         }
396 
397         if (pkg.getPackageName().equals("android")) {
398             mPm.setPlatformPackage(pkg, pkgSetting);
399         }
400 
401         ArrayList<AndroidPackage> clientLibPkgs = null;
402         // writer
403         synchronized (mPm.mLock) {
404             if (!ArrayUtils.isEmpty(reconciledPkg.mAllowedSharedLibraryInfos)) {
405                 for (SharedLibraryInfo info : reconciledPkg.mAllowedSharedLibraryInfos) {
406                     mSharedLibraries.commitSharedLibraryInfoLPw(info);
407                 }
408                 final Map<String, AndroidPackage> combinedSigningDetails =
409                         reconciledPkg.getCombinedAvailablePackages();
410                 try {
411                     // Shared libraries for the package need to be updated.
412                     mSharedLibraries.updateSharedLibrariesLPw(pkg, pkgSetting, null, null,
413                             combinedSigningDetails);
414                 } catch (PackageManagerException e) {
415                     Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
416                 }
417                 // Update all applications that use this library. Skip when booting
418                 // since this will be done after all packages are scaned.
419                 if ((scanFlags & SCAN_BOOTING) == 0) {
420                     clientLibPkgs = mSharedLibraries.updateAllSharedLibrariesLPw(pkg, pkgSetting,
421                             combinedSigningDetails);
422                 }
423             }
424         }
425         if (reconciledPkg.mInstallResult != null) {
426             reconciledPkg.mInstallResult.mLibraryConsumers = clientLibPkgs;
427         }
428 
429         if ((scanFlags & SCAN_BOOTING) != 0) {
430             // No apps can run during boot scan, so they don't need to be frozen
431         } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
432             // Caller asked to not kill app, so it's probably not frozen
433         } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
434             // Caller asked us to ignore frozen check for some reason; they
435             // probably didn't know the package name
436         } else {
437             // We're doing major surgery on this package, so it better be frozen
438             // right now to keep it from launching
439             mPm.snapshotComputer().checkPackageFrozen(pkgName);
440         }
441 
442         final boolean isReplace =
443                 reconciledPkg.mPrepareResult != null && reconciledPkg.mPrepareResult.mReplace;
444         // Also need to kill any apps that are dependent on the library, except the case of
445         // installation of new version static shared library.
446         if (clientLibPkgs != null) {
447             if (pkg.getStaticSharedLibName() == null || isReplace) {
448                 for (int i = 0; i < clientLibPkgs.size(); i++) {
449                     AndroidPackage clientPkg = clientLibPkgs.get(i);
450                     mPm.killApplication(clientPkg.getPackageName(),
451                             clientPkg.getUid(), "update lib");
452                 }
453             }
454         }
455 
456         // writer
457         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
458 
459         synchronized (mPm.mLock) {
460             // We don't expect installation to fail beyond this point
461             // Add the new setting to mSettings
462             mPm.mSettings.insertPackageSettingLPw(pkgSetting, pkg);
463             // Add the new setting to mPackages
464             mPm.mPackages.put(pkg.getPackageName(), pkg);
465             if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
466                 mApexManager.registerApkInApex(pkg);
467             }
468 
469             // Add the package's KeySets to the global KeySetManagerService
470             KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
471             ksms.addScannedPackageLPw(pkg);
472 
473             final Computer snapshot = mPm.snapshotComputer();
474             mPm.mComponentResolver.addAllComponents(pkg, chatty, mPm.mSetupWizardPackage, snapshot);
475             mPm.mAppsFilter.addPackage(snapshot, pkgSetting, isReplace);
476             mPm.addAllPackageProperties(pkg);
477 
478             if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) {
479                 mPm.mDomainVerificationManager.addPackage(pkgSetting);
480             } else {
481                 mPm.mDomainVerificationManager.migrateState(oldPkgSetting, pkgSetting);
482             }
483 
484             int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
485             StringBuilder r = null;
486             int i;
487             for (i = 0; i < collectionSize; i++) {
488                 ParsedInstrumentation a = pkg.getInstrumentations().get(i);
489                 ComponentMutateUtils.setPackageName(a, pkg.getPackageName());
490                 mPm.addInstrumentation(a.getComponentName(), a);
491                 if (chatty) {
492                     if (r == null) {
493                         r = new StringBuilder(256);
494                     } else {
495                         r.append(' ');
496                     }
497                     r.append(a.getName());
498                 }
499             }
500             if (r != null) {
501                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
502             }
503 
504             final List<String> protectedBroadcasts = pkg.getProtectedBroadcasts();
505             if (!protectedBroadcasts.isEmpty()) {
506                 synchronized (mPm.mProtectedBroadcasts) {
507                     mPm.mProtectedBroadcasts.addAll(protectedBroadcasts);
508                 }
509             }
510 
511             mPm.mPermissionManager.onPackageAdded(pkg,
512                     (scanFlags & SCAN_AS_INSTANT_APP) != 0, oldPkg);
513         }
514 
515         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
516     }
517 
installExistingPackageAsUser(@ullable String packageName, @UserIdInt int userId, @PackageManager.InstallFlags int installFlags, @PackageManager.InstallReason int installReason, @Nullable List<String> allowlistedRestrictedPermissions, @Nullable IntentSender intentSender)518     public int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
519             @PackageManager.InstallFlags int installFlags,
520             @PackageManager.InstallReason int installReason,
521             @Nullable List<String> allowlistedRestrictedPermissions,
522             @Nullable IntentSender intentSender) {
523         if (DEBUG_INSTALL) {
524             Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId
525                     + " installFlags=" + installFlags + " installReason=" + installReason
526                     + " allowlistedRestrictedPermissions=" + allowlistedRestrictedPermissions);
527         }
528 
529         final int callingUid = Binder.getCallingUid();
530         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
531                 != PackageManager.PERMISSION_GRANTED
532                 && mContext.checkCallingOrSelfPermission(
533                 android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
534                 != PackageManager.PERMISSION_GRANTED) {
535             throw new SecurityException("Neither user " + callingUid + " nor current process has "
536                     + android.Manifest.permission.INSTALL_PACKAGES + ".");
537         }
538         PackageSetting pkgSetting;
539         final Computer preLockSnapshot = mPm.snapshotComputer();
540         preLockSnapshot.enforceCrossUserPermission(callingUid, userId,
541                 true /* requireFullPermission */, true /* checkShell */,
542                 "installExistingPackage for user " + userId);
543         if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
544             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
545         }
546 
547         final long callingId = Binder.clearCallingIdentity();
548         try {
549             boolean installed = false;
550             final boolean instantApp =
551                     (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
552             final boolean fullApp =
553                     (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
554 
555             // writer
556             synchronized (mPm.mLock) {
557                 final Computer snapshot = mPm.snapshotComputer();
558                 pkgSetting = mPm.mSettings.getPackageLPr(packageName);
559                 if (pkgSetting == null) {
560                     return PackageManager.INSTALL_FAILED_INVALID_URI;
561                 }
562                 if (!snapshot.canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
563                     // only allow the existing package to be used if it's installed as a full
564                     // application for at least one user
565                     boolean installAllowed = false;
566                     for (int checkUserId : mPm.mUserManager.getUserIds()) {
567                         installAllowed = !pkgSetting.getInstantApp(checkUserId);
568                         if (installAllowed) {
569                             break;
570                         }
571                     }
572                     if (!installAllowed) {
573                         return PackageManager.INSTALL_FAILED_INVALID_URI;
574                     }
575                 }
576                 if (!pkgSetting.getInstalled(userId)) {
577                     pkgSetting.setInstalled(true, userId);
578                     pkgSetting.setHidden(false, userId);
579                     pkgSetting.setInstallReason(installReason, userId);
580                     pkgSetting.setUninstallReason(PackageManager.UNINSTALL_REASON_UNKNOWN, userId);
581                     pkgSetting.setFirstInstallTime(System.currentTimeMillis(), userId);
582                     mPm.mSettings.writePackageRestrictionsLPr(userId);
583                     mPm.mSettings.writeKernelMappingLPr(pkgSetting);
584                     installed = true;
585                 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
586                     // upgrade app from instant to full; we don't allow app downgrade
587                     installed = true;
588                 }
589                 ScanPackageUtils.setInstantAppForUser(mPm.mInjector, pkgSetting, userId, instantApp,
590                         fullApp);
591             }
592 
593             if (installed) {
594                 if (pkgSetting.getPkg() != null) {
595                     final PermissionManagerServiceInternal.PackageInstalledParams.Builder
596                             permissionParamsBuilder =
597                             new PermissionManagerServiceInternal.PackageInstalledParams.Builder();
598                     if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
599                             != 0) {
600                         permissionParamsBuilder.setAllowlistedRestrictedPermissions(
601                                 pkgSetting.getPkg().getRequestedPermissions());
602                     }
603                     mPm.mPermissionManager.onPackageInstalled(pkgSetting.getPkg(),
604                             Process.INVALID_UID /* previousAppId */,
605                             permissionParamsBuilder.build(), userId);
606 
607                     synchronized (mPm.mInstallLock) {
608                         // We don't need to freeze for a brand new install
609                         mAppDataHelper.prepareAppDataAfterInstallLIF(pkgSetting.getPkg());
610                     }
611                 }
612                 mPm.sendPackageAddedForUser(mPm.snapshotComputer(), packageName, pkgSetting, userId,
613                         DataLoaderType.NONE);
614                 synchronized (mPm.mLock) {
615                     mPm.updateSequenceNumberLP(pkgSetting, new int[]{ userId });
616                 }
617                 // start async restore with no post-install since we finish install here
618                 PackageInstalledInfo res = new PackageInstalledInfo(
619                         PackageManager.INSTALL_SUCCEEDED);
620                 res.mPkg = pkgSetting.getPkg();
621                 res.mNewUsers = new int[]{ userId };
622 
623                 PostInstallData postInstallData =
624                         new PostInstallData(null, res, () -> {
625                             mPm.restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
626                                     userId);
627                             if (intentSender != null) {
628                                 onRestoreComplete(res.mReturnCode, mContext, intentSender);
629                             }
630                         });
631                 restoreAndPostInstall(userId, res, postInstallData);
632             }
633         } finally {
634             Binder.restoreCallingIdentity(callingId);
635         }
636 
637         return PackageManager.INSTALL_SUCCEEDED;
638     }
639 
onRestoreComplete(int returnCode, Context context, IntentSender target)640     private static void onRestoreComplete(int returnCode, Context context, IntentSender target) {
641         Intent fillIn = new Intent();
642         fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
643                 PackageManager.installStatusToPublicStatus(returnCode));
644         try {
645             final BroadcastOptions options = BroadcastOptions.makeBasic();
646             options.setPendingIntentBackgroundActivityLaunchAllowed(false);
647             target.sendIntent(context, 0, fillIn, null /* onFinished*/, null /* handler */,
648                     null /* requiredPermission */, options.toBundle());
649         } catch (IntentSender.SendIntentException ignored) {
650         }
651     }
652 
653     /** @param data Post-install is performed only if this is non-null. */
restoreAndPostInstall( int userId, PackageInstalledInfo res, @Nullable PostInstallData data)654     public void restoreAndPostInstall(
655             int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
656         if (DEBUG_INSTALL) {
657             Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.mPkg);
658         }
659 
660         // A restore should be requested at this point if (a) the install
661         // succeeded, (b) the operation is not an update.
662         final boolean update = res.mRemovedInfo != null
663                 && res.mRemovedInfo.mRemovedPackage != null;
664         boolean doRestore = !update && res.mPkg != null;
665 
666         // Set up the post-install work request bookkeeping.  This will be used
667         // and cleaned up by the post-install event handling regardless of whether
668         // there's a restore pass performed.  Token values are >= 1.
669         int token;
670         if (mPm.mNextInstallToken < 0) mPm.mNextInstallToken = 1;
671         token = mPm.mNextInstallToken++;
672         if (data != null) {
673             mPm.mRunningInstalls.put(token, data);
674         } else if (DEBUG_INSTALL) {
675             Log.v(TAG, "No post-install required for " + token);
676         }
677 
678         if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
679 
680         if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
681             // Pass responsibility to the Backup Manager.  It will perform a
682             // restore if appropriate, then pass responsibility back to the
683             // Package Manager to run the post-install observer callbacks
684             // and broadcasts.
685             if (res.mFreezer != null) {
686                 res.mFreezer.close();
687             }
688             doRestore = performBackupManagerRestore(userId, token, res);
689         }
690 
691         // If this is an update to a package that might be potentially downgraded, then we
692         // need to check with the rollback manager whether there's any userdata that might
693         // need to be snapshotted or restored for the package.
694         //
695         // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL.
696         if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
697             doRestore = performRollbackManagerRestore(userId, token, res, data);
698         }
699 
700         if (!doRestore) {
701             // No restore possible, or the Backup Manager was mysteriously not
702             // available -- just fire the post-install work request directly.
703             if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
704 
705             Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
706 
707             Message msg = mPm.mHandler.obtainMessage(POST_INSTALL, token, 0);
708             mPm.mHandler.sendMessage(msg);
709         }
710     }
711 
712     /**
713      * Perform Backup Manager restore for a given {@link PackageInstalledInfo}.
714      * Returns whether the restore successfully completed.
715      */
performBackupManagerRestore(int userId, int token, PackageInstalledInfo res)716     private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) {
717         IBackupManager iBackupManager = mInjector.getIBackupManager();
718         if (iBackupManager != null) {
719             // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
720             // in the BackupManager. USER_ALL is used in compatibility tests.
721             if (userId == UserHandle.USER_ALL) {
722                 userId = UserHandle.USER_SYSTEM;
723             }
724             if (DEBUG_INSTALL) {
725                 Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId);
726             }
727             Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
728             try {
729                 if (iBackupManager.isUserReadyForBackup(userId)) {
730                     iBackupManager.restoreAtInstallForUser(
731                             userId, res.mPkg.getPackageName(), token);
732                 } else {
733                     Slog.w(TAG, "User " + userId + " is not ready. Restore at install "
734                             + "didn't take place.");
735                     return false;
736                 }
737             } catch (RemoteException e) {
738                 // can't happen; the backup manager is local
739             } catch (Exception e) {
740                 Slog.e(TAG, "Exception trying to enqueue restore", e);
741                 return false;
742             }
743         } else {
744             Slog.e(TAG, "Backup Manager not found!");
745             return false;
746         }
747         return true;
748     }
749 
750     /**
751      * Perform Rollback Manager restore for a given {@link PackageInstalledInfo}.
752      * Returns whether the restore successfully completed.
753      */
performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res, PostInstallData data)754     private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res,
755             PostInstallData data) {
756         final String packageName = res.mPkg.getPackageName();
757         final int[] allUsers = mPm.mUserManager.getUserIds();
758         final int[] installedUsers;
759 
760         final PackageSetting ps;
761         int appId = -1;
762         long ceDataInode = -1;
763         synchronized (mPm.mLock) {
764             ps = mPm.mSettings.getPackageLPr(packageName);
765             if (ps != null) {
766                 appId = ps.getAppId();
767                 ceDataInode = ps.getCeDataInode(userId);
768             }
769 
770             // NOTE: We ignore the user specified in the InstallParam because we know this is
771             // an update, and hence need to restore data for all installed users.
772             installedUsers = ps.queryInstalledUsers(allUsers, true);
773         }
774 
775         boolean doSnapshotOrRestore = data != null && data.args != null
776                 && ((data.args.mInstallFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0
777                 || (data.args.mInstallFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0);
778 
779         if (ps != null && doSnapshotOrRestore) {
780             final String seInfo = AndroidPackageUtils.getSeInfo(res.mPkg, ps);
781             final RollbackManagerInternal rollbackManager =
782                     mInjector.getLocalService(RollbackManagerInternal.class);
783             rollbackManager.snapshotAndRestoreUserData(packageName,
784                     UserHandle.toUserHandles(installedUsers), appId, ceDataInode, seInfo, token);
785             return true;
786         }
787         return false;
788     }
789 
processInstallRequests(boolean success, List<InstallRequest> installRequests)790     public void processInstallRequests(boolean success, List<InstallRequest> installRequests) {
791         List<InstallRequest> apexInstallRequests = new ArrayList<>();
792         List<InstallRequest> apkInstallRequests = new ArrayList<>();
793         for (InstallRequest request : installRequests) {
794             if ((request.mArgs.mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
795                 apexInstallRequests.add(request);
796             } else {
797                 apkInstallRequests.add(request);
798             }
799         }
800         // Note: supporting multi package install of both APEXes and APKs might requir some
801         // thinking to ensure atomicity of the install.
802         if (!apexInstallRequests.isEmpty() && !apkInstallRequests.isEmpty()) {
803             // This should've been caught at the validation step, but for some reason wasn't.
804             throw new IllegalStateException(
805                     "Attempted to do a multi package install of both APEXes and APKs");
806         }
807         if (!apexInstallRequests.isEmpty()) {
808             if (success) {
809                 // Since installApexPackages requires talking to external service (apexd), we
810                 // schedule to run it async. Once it finishes, it will resume the install.
811                 Thread t = new Thread(() -> installApexPackagesTraced(apexInstallRequests),
812                         "installApexPackages");
813                 t.start();
814             } else {
815                 // Non-staged APEX installation failed somewhere before
816                 // processInstallRequestAsync. In that case just notify the observer about the
817                 // failure.
818                 InstallRequest request = apexInstallRequests.get(0);
819                 mPm.notifyInstallObserver(request.mInstallResult,
820                         request.mArgs.mObserver);
821             }
822             return;
823         }
824         if (success) {
825             for (InstallRequest request : apkInstallRequests) {
826                 request.mArgs.doPreInstall(request.mInstallResult.mReturnCode);
827             }
828             synchronized (mPm.mInstallLock) {
829                 installPackagesTracedLI(apkInstallRequests);
830             }
831             for (InstallRequest request : apkInstallRequests) {
832                 request.mArgs.doPostInstall(
833                         request.mInstallResult.mReturnCode, request.mInstallResult.mUid);
834             }
835         }
836         for (InstallRequest request : apkInstallRequests) {
837             restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
838                     request.mInstallResult,
839                     new PostInstallData(request.mArgs,
840                             request.mInstallResult, null));
841         }
842     }
843 
installApexPackagesTraced(List<InstallRequest> requests)844     private void installApexPackagesTraced(List<InstallRequest> requests) {
845         try {
846             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installApexPackages");
847             installApexPackages(requests);
848         } finally {
849             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
850         }
851     }
852 
installApexPackages(List<InstallRequest> requests)853     private void installApexPackages(List<InstallRequest> requests) {
854         if (requests.isEmpty()) {
855             return;
856         }
857         if (requests.size() != 1) {
858             throw new IllegalStateException(
859                     "Only a non-staged install of a single APEX is supported");
860         }
861         InstallRequest request = requests.get(0);
862         try {
863             // Should directory scanning logic be moved to ApexManager for better test coverage?
864             final File dir = request.mArgs.mOriginInfo.mResolvedFile;
865             final File[] apexes = dir.listFiles();
866             if (apexes == null) {
867                 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
868                         dir.getAbsolutePath() + " is not a directory");
869             }
870             if (apexes.length != 1) {
871                 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
872                         "Expected exactly one .apex file under " + dir.getAbsolutePath()
873                                 + " got: " + apexes.length);
874             }
875             try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) {
876                 mApexManager.installPackage(apexes[0], packageParser);
877             }
878         } catch (PackageManagerException e) {
879             request.mInstallResult.setError("APEX installation failed", e);
880         }
881         PackageManagerService.invalidatePackageInfoCache();
882         mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
883     }
884 
885     @GuardedBy("mPm.mInstallLock")
installPackagesTracedLI(List<InstallRequest> requests)886     private void installPackagesTracedLI(List<InstallRequest> requests) {
887         try {
888             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
889             installPackagesLI(requests);
890         } finally {
891             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
892         }
893     }
894 
895     /**
896      * Installs one or more packages atomically. This operation is broken up into four phases:
897      * <ul>
898      *     <li><b>Prepare</b>
899      *         <br/>Analyzes any current install state, parses the package and does initial
900      *         validation on it.</li>
901      *     <li><b>Scan</b>
902      *         <br/>Interrogates the parsed packages given the context collected in prepare.</li>
903      *     <li><b>Reconcile</b>
904      *         <br/>Validates scanned packages in the context of each other and the current system
905      *         state to ensure that the install will be successful.
906      *     <li><b>Commit</b>
907      *         <br/>Commits all scanned packages and updates system state. This is the only place
908      *         that system state may be modified in the install flow and all predictable errors
909      *         must be determined before this phase.</li>
910      * </ul>
911      *
912      * Failure at any phase will result in a full failure to install all packages.
913      */
914     @GuardedBy("mPm.mInstallLock")
installPackagesLI(List<InstallRequest> requests)915     private void installPackagesLI(List<InstallRequest> requests) {
916         final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
917         final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
918         final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
919         final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
920         final Map<String, Settings.VersionInfo> versionInfos = new ArrayMap<>(requests.size());
921         final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
922         boolean success = false;
923         try {
924             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
925             for (InstallRequest request : requests) {
926                 // TODO(b/109941548): remove this once we've pulled everything from it and into
927                 //                    scan, reconcile or commit.
928                 final PrepareResult prepareResult;
929                 try {
930                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
931                     prepareResult =
932                             preparePackageLI(request.mArgs, request.mInstallResult);
933                 } catch (PrepareFailure prepareFailure) {
934                     request.mInstallResult.setError(prepareFailure.error,
935                             prepareFailure.getMessage());
936                     request.mInstallResult.mOrigPackage = prepareFailure.mConflictingPackage;
937                     request.mInstallResult.mOrigPermission = prepareFailure.mConflictingPermission;
938                     return;
939                 } finally {
940                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
941                 }
942                 request.mInstallResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
943                 request.mInstallResult.mInstallerPackageName =
944                         request.mArgs.mInstallSource.installerPackageName;
945 
946                 final String packageName = prepareResult.mPackageToScan.getPackageName();
947                 prepareResults.put(packageName, prepareResult);
948                 installResults.put(packageName, request.mInstallResult);
949                 installArgs.put(packageName, request.mArgs);
950                 try {
951                     final ScanResult result = scanPackageTracedLI(
952                             prepareResult.mPackageToScan, prepareResult.mParseFlags,
953                             prepareResult.mScanFlags, System.currentTimeMillis(),
954                             request.mArgs.mUser, request.mArgs.mAbiOverride);
955                     if (null != preparedScans.put(result.mPkgSetting.getPkg().getPackageName(),
956                             result)) {
957                         request.mInstallResult.setError(
958                                 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
959                                 "Duplicate package "
960                                         + result.mPkgSetting.getPkg().getPackageName()
961                                         + " in multi-package install request.");
962                         return;
963                     }
964                     if (!checkNoAppStorageIsConsistent(
965                             result.mRequest.mOldPkg, result.mPkgSetting.getPkg())) {
966                         // TODO: INSTALL_FAILED_UPDATE_INCOMPATIBLE is about incomptabible
967                         //  signatures. Is there a better error code?
968                         request.mInstallResult.setError(
969                                 INSTALL_FAILED_UPDATE_INCOMPATIBLE,
970                                 "Update attempted to change value of "
971                                         + PackageManager.PROPERTY_NO_APP_DATA_STORAGE);
972                         return;
973                     }
974                     createdAppId.put(packageName, optimisticallyRegisterAppId(result));
975                     versionInfos.put(result.mPkgSetting.getPkg().getPackageName(),
976                             mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg()));
977                 } catch (PackageManagerException e) {
978                     request.mInstallResult.setError("Scanning Failed.", e);
979                     return;
980                 }
981             }
982             ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
983                     installResults, prepareResults,
984                     Collections.unmodifiableMap(mPm.mPackages), versionInfos);
985             CommitRequest commitRequest = null;
986             synchronized (mPm.mLock) {
987                 Map<String, ReconciledPackage> reconciledPackages;
988                 try {
989                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
990                     reconciledPackages = ReconcilePackageUtils.reconcilePackages(
991                             reconcileRequest, mSharedLibraries,
992                             mPm.mSettings.getKeySetManagerService(), mPm.mSettings);
993                 } catch (ReconcileFailure e) {
994                     for (InstallRequest request : requests) {
995                         request.mInstallResult.setError("Reconciliation failed...", e);
996                     }
997                     return;
998                 } finally {
999                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1000                 }
1001                 try {
1002                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
1003                     commitRequest = new CommitRequest(reconciledPackages,
1004                             mPm.mUserManager.getUserIds());
1005                     commitPackagesLocked(commitRequest);
1006                     success = true;
1007                 } finally {
1008                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1009                 }
1010             }
1011             executePostCommitSteps(commitRequest);
1012         } finally {
1013             if (success) {
1014                 for (InstallRequest request : requests) {
1015                     final InstallArgs args = request.mArgs;
1016                     if (args.mDataLoaderType != DataLoaderType.INCREMENTAL) {
1017                         continue;
1018                     }
1019                     if (args.mSigningDetails.getSignatureSchemeVersion() != SIGNING_BLOCK_V4) {
1020                         continue;
1021                     }
1022                     // For incremental installs, we bypass the verifier prior to install. Now
1023                     // that we know the package is valid, send a notice to the verifier with
1024                     // the root hash of the base.apk.
1025                     final String baseCodePath = request.mInstallResult.mPkg.getBaseApkPath();
1026                     final String[] splitCodePaths = request.mInstallResult.mPkg.getSplitCodePaths();
1027                     final Uri originUri = Uri.fromFile(args.mOriginInfo.mResolvedFile);
1028                     final int verificationId = mPm.mPendingVerificationToken++;
1029                     final String rootHashString = PackageManagerServiceUtils
1030                             .buildVerificationRootHashString(baseCodePath, splitCodePaths);
1031                     VerificationUtils.broadcastPackageVerified(verificationId, originUri,
1032                             PackageManager.VERIFICATION_ALLOW, rootHashString,
1033                             args.mDataLoaderType, args.getUser(), mContext);
1034                 }
1035             } else {
1036                 for (ScanResult result : preparedScans.values()) {
1037                     if (createdAppId.getOrDefault(result.mRequest.mParsedPackage.getPackageName(),
1038                             false)) {
1039                         cleanUpAppIdCreation(result);
1040                     }
1041                 }
1042                 // TODO(b/194319951): create a more descriptive reason than unknown
1043                 // mark all non-failure installs as UNKNOWN so we do not treat them as success
1044                 for (InstallRequest request : requests) {
1045                     if (request.mInstallResult.mFreezer != null) {
1046                         request.mInstallResult.mFreezer.close();
1047                     }
1048                     if (request.mInstallResult.mReturnCode == PackageManager.INSTALL_SUCCEEDED) {
1049                         request.mInstallResult.mReturnCode = PackageManager.INSTALL_UNKNOWN;
1050                     }
1051                 }
1052             }
1053             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1054         }
1055     }
1056 
1057     @GuardedBy("mPm.mInstallLock")
checkNoAppStorageIsConsistent(AndroidPackage oldPkg, AndroidPackage newPkg)1058     private boolean checkNoAppStorageIsConsistent(AndroidPackage oldPkg, AndroidPackage newPkg) {
1059         if (oldPkg == null) {
1060             // New install, nothing to check against.
1061             return true;
1062         }
1063         final PackageManager.Property curProp =
1064                 oldPkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE);
1065         final PackageManager.Property newProp =
1066                 newPkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE);
1067         if (curProp == null || !curProp.getBoolean()) {
1068             return newProp == null || !newProp.getBoolean();
1069         }
1070         return newProp != null && newProp.getBoolean();
1071     }
1072 
1073     @GuardedBy("mPm.mInstallLock")
preparePackageLI(InstallArgs args, PackageInstalledInfo res)1074     private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
1075             throws PrepareFailure {
1076         final int installFlags = args.mInstallFlags;
1077         final File tmpPackageFile = new File(args.getCodePath());
1078         final boolean onExternal = args.mVolumeUuid != null;
1079         final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
1080         final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
1081         final boolean virtualPreload =
1082                 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1083         final boolean isRollback = args.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK;
1084         @PackageManagerService.ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
1085         if (args.mMoveInfo != null) {
1086             // moving a complete application; perform an initial scan on the new install location
1087             scanFlags |= SCAN_INITIAL;
1088         }
1089         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
1090             scanFlags |= SCAN_DONT_KILL_APP;
1091         }
1092         if (instantApp) {
1093             scanFlags |= SCAN_AS_INSTANT_APP;
1094         }
1095         if (fullApp) {
1096             scanFlags |= SCAN_AS_FULL_APP;
1097         }
1098         if (virtualPreload) {
1099             scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
1100         }
1101 
1102         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
1103 
1104         // Validity check
1105         if (instantApp && onExternal) {
1106             Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
1107             throw new PrepareFailure(PackageManager.INSTALL_FAILED_SESSION_INVALID);
1108         }
1109 
1110         // Retrieve PackageSettings and parse package
1111         @ParsingPackageUtils.ParseFlags final int parseFlags =
1112                 mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_CHATTY
1113                         | ParsingPackageUtils.PARSE_ENFORCE_CODE
1114                         | (onExternal ? ParsingPackageUtils.PARSE_EXTERNAL_STORAGE : 0);
1115 
1116         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
1117         final ParsedPackage parsedPackage;
1118         try (PackageParser2 pp = mPm.mInjector.getPreparingPackageParser()) {
1119             parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
1120             AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
1121         } catch (PackageManagerException e) {
1122             throw new PrepareFailure("Failed parse during installPackageLI", e);
1123         } finally {
1124             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1125         }
1126 
1127         // Instant apps have several additional install-time checks.
1128         if (instantApp) {
1129             if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {
1130                 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
1131                         + " does not target at least O");
1132                 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
1133                         "Instant app package must target at least O");
1134             }
1135             if (parsedPackage.getSharedUserId() != null) {
1136                 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
1137                         + " may not declare sharedUserId.");
1138                 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
1139                         "Instant app package may not declare a sharedUserId");
1140             }
1141         }
1142 
1143         if (parsedPackage.isStaticSharedLibrary()) {
1144             // Static shared libraries have synthetic package names
1145             PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage);
1146 
1147             // No static shared libs on external storage
1148             if (onExternal) {
1149                 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
1150                 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1151                         "Packages declaring static-shared libs cannot be updated");
1152             }
1153         }
1154 
1155         String pkgName = res.mName = parsedPackage.getPackageName();
1156         if (parsedPackage.isTestOnly()) {
1157             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
1158                 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
1159             }
1160         }
1161 
1162         // either use what we've been given or parse directly from the APK
1163         if (args.mSigningDetails != SigningDetails.UNKNOWN) {
1164             parsedPackage.setSigningDetails(args.mSigningDetails);
1165         } else {
1166             final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
1167             final ParseResult<SigningDetails> result = ParsingPackageUtils.getSigningDetails(
1168                     input, parsedPackage, false /*skipVerify*/);
1169             if (result.isError()) {
1170                 throw new PrepareFailure("Failed collect during installPackageLI",
1171                         result.getException());
1172             }
1173             parsedPackage.setSigningDetails(result.getResult());
1174         }
1175 
1176         if (instantApp && parsedPackage.getSigningDetails().getSignatureSchemeVersion()
1177                 < SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2) {
1178             Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
1179                     + " is not signed with at least APK Signature Scheme v2");
1180             throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
1181                     "Instant app package must be signed with APK Signature Scheme v2 or greater");
1182         }
1183 
1184         boolean systemApp = false;
1185         boolean replace = false;
1186         synchronized (mPm.mLock) {
1187             // Check if installing already existing package
1188             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
1189                 String oldName = mPm.mSettings.getRenamedPackageLPr(pkgName);
1190                 if (parsedPackage.getOriginalPackages().contains(oldName)
1191                         && mPm.mPackages.containsKey(oldName)) {
1192                     // This package is derived from an original package,
1193                     // and this device has been updating from that original
1194                     // name.  We must continue using the original name, so
1195                     // rename the new package here.
1196                     parsedPackage.setPackageName(oldName);
1197                     pkgName = parsedPackage.getPackageName();
1198                     replace = true;
1199                     if (DEBUG_INSTALL) {
1200                         Slog.d(TAG, "Replacing existing renamed package: oldName="
1201                                 + oldName + " pkgName=" + pkgName);
1202                     }
1203                 } else if (mPm.mPackages.containsKey(pkgName)) {
1204                     // This package, under its official name, already exists
1205                     // on the device; we should replace it.
1206                     replace = true;
1207                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing package: " + pkgName);
1208                 }
1209 
1210                 if (replace) {
1211                     // Prevent apps opting out from runtime permissions
1212                     AndroidPackage oldPackage = mPm.mPackages.get(pkgName);
1213                     final int oldTargetSdk = oldPackage.getTargetSdkVersion();
1214                     final int newTargetSdk = parsedPackage.getTargetSdkVersion();
1215                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
1216                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
1217                         throw new PrepareFailure(
1218                                 PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
1219                                 "Package " + parsedPackage.getPackageName()
1220                                         + " new target SDK " + newTargetSdk
1221                                         + " doesn't support runtime permissions but the old"
1222                                         + " target SDK " + oldTargetSdk + " does.");
1223                     }
1224                     // Prevent persistent apps from being updated
1225                     if (oldPackage.isPersistent()
1226                             && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {
1227                         throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,
1228                                 "Package " + oldPackage.getPackageName() + " is a persistent app. "
1229                                         + "Persistent apps are not updateable.");
1230                     }
1231                 }
1232             }
1233 
1234             PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
1235             PackageSetting signatureCheckPs = ps;
1236 
1237             // SDK libs can have other major versions with different package names.
1238             if (signatureCheckPs == null && parsedPackage.isSdkLibrary()) {
1239                 WatchedLongSparseArray<SharedLibraryInfo> libraryInfos =
1240                         mSharedLibraries.getSharedLibraryInfos(
1241                                 parsedPackage.getSdkLibName());
1242                 if (libraryInfos != null && libraryInfos.size() > 0) {
1243                     // Any existing version would do.
1244                     SharedLibraryInfo libraryInfo = libraryInfos.valueAt(0);
1245                     signatureCheckPs = mPm.mSettings.getPackageLPr(libraryInfo.getPackageName());
1246                 }
1247             }
1248 
1249             // Static shared libs have same package with different versions where
1250             // we internally use a synthetic package name to allow multiple versions
1251             // of the same package, therefore we need to compare signatures against
1252             // the package setting for the latest library version.
1253             if (parsedPackage.isStaticSharedLibrary()) {
1254                 SharedLibraryInfo libraryInfo =
1255                         mSharedLibraries.getLatestStaticSharedLibraVersionLPr(parsedPackage);
1256                 if (libraryInfo != null) {
1257                     signatureCheckPs = mPm.mSettings.getPackageLPr(libraryInfo.getPackageName());
1258                 }
1259             }
1260 
1261             if (signatureCheckPs != null) {
1262                 if (DEBUG_INSTALL) {
1263                     Slog.d(TAG,
1264                             "Existing package for signature checking: " + signatureCheckPs);
1265                 }
1266 
1267                 // Quick validity check that we're signed correctly if updating;
1268                 // we'll check this again later when scanning, but we want to
1269                 // bail early here before tripping over redefined permissions.
1270                 final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
1271                 final SharedUserSetting signatureCheckSus = mPm.mSettings.getSharedUserSettingLPr(
1272                         signatureCheckPs);
1273                 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, signatureCheckSus,
1274                         scanFlags)) {
1275                     if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
1276                         throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
1277                                 + parsedPackage.getPackageName() + " upgrade keys do not match the "
1278                                 + "previously installed version");
1279                     }
1280                 } else {
1281                     try {
1282                         final boolean compareCompat =
1283                                 ReconcilePackageUtils.isCompatSignatureUpdateNeeded(
1284                                         mPm.getSettingsVersionForPackage(parsedPackage));
1285                         final boolean compareRecover =
1286                                 ReconcilePackageUtils.isRecoverSignatureUpdateNeeded(
1287                                         mPm.getSettingsVersionForPackage(parsedPackage));
1288                         // We don't care about disabledPkgSetting on install for now.
1289                         final boolean compatMatch =
1290                                 PackageManagerServiceUtils.verifySignatures(signatureCheckPs,
1291                                         signatureCheckSus, null,
1292                                 parsedPackage.getSigningDetails(), compareCompat, compareRecover,
1293                                 isRollback);
1294                         // The new KeySets will be re-added later in the scanning process.
1295                         if (compatMatch) {
1296                             synchronized (mPm.mLock) {
1297                                 ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName());
1298                             }
1299                         }
1300                     } catch (PackageManagerException e) {
1301                         throw new PrepareFailure(e.error, e.getMessage());
1302                     }
1303                 }
1304             }
1305 
1306             if (ps != null) {
1307                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
1308 
1309                 if (ps.getPkg() != null) {
1310                     systemApp = ps.getPkg().isSystem();
1311                 }
1312                 res.mOrigUsers = ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true);
1313             }
1314 
1315             final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups());
1316             for (int groupNum = 0; groupNum < numGroups; groupNum++) {
1317                 final ParsedPermissionGroup group =
1318                         parsedPackage.getPermissionGroups().get(groupNum);
1319                 final PermissionGroupInfo sourceGroup = mPm.getPermissionGroupInfo(group.getName(),
1320                         0);
1321 
1322                 if (sourceGroup != null && cannotInstallWithBadPermissionGroups(parsedPackage)) {
1323                     final String sourcePackageName = sourceGroup.packageName;
1324 
1325                     if ((replace || !parsedPackage.getPackageName().equals(sourcePackageName))
1326                             && !doesSignatureMatchForPermissions(sourcePackageName, parsedPackage,
1327                             scanFlags)) {
1328                         EventLog.writeEvent(0x534e4554, "146211400", -1,
1329                                 parsedPackage.getPackageName());
1330 
1331                         throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP,
1332                                 "Package "
1333                                         + parsedPackage.getPackageName()
1334                                         + " attempting to redeclare permission group "
1335                                         + group.getName() + " already owned by "
1336                                         + sourcePackageName);
1337                     }
1338                 }
1339             }
1340 
1341             // TODO: Move logic for checking permission compatibility into PermissionManagerService
1342             final int n = ArrayUtils.size(parsedPackage.getPermissions());
1343             for (int i = n - 1; i >= 0; i--) {
1344                 final ParsedPermission perm = parsedPackage.getPermissions().get(i);
1345                 final Permission bp = mPm.mPermissionManager.getPermissionTEMP(perm.getName());
1346 
1347                 // Don't allow anyone but the system to define ephemeral permissions.
1348                 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
1349                         && !systemApp) {
1350                     Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName()
1351                             + " attempting to delcare ephemeral permission "
1352                             + perm.getName() + "; Removing ephemeral.");
1353                     ComponentMutateUtils.setProtectionLevel(perm,
1354                             perm.getProtectionLevel() & ~PermissionInfo.PROTECTION_FLAG_INSTANT);
1355                 }
1356 
1357                 // Check whether the newly-scanned package wants to define an already-defined perm
1358                 if (bp != null) {
1359                     final String sourcePackageName = bp.getPackageName();
1360 
1361                     if (!doesSignatureMatchForPermissions(sourcePackageName, parsedPackage,
1362                             scanFlags)) {
1363                         // If the owning package is the system itself, we log but allow
1364                         // install to proceed; we fail the install on all other permission
1365                         // redefinitions.
1366                         if (!sourcePackageName.equals("android")) {
1367                             throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION,
1368                                     "Package "
1369                                             + parsedPackage.getPackageName()
1370                                             + " attempting to redeclare permission "
1371                                             + perm.getName() + " already owned by "
1372                                             + sourcePackageName)
1373                                     .conflictsWithExistingPermission(perm.getName(),
1374                                             sourcePackageName);
1375                         } else {
1376                             Slog.w(TAG, "Package " + parsedPackage.getPackageName()
1377                                     + " attempting to redeclare system permission "
1378                                     + perm.getName() + "; ignoring new declaration");
1379                             parsedPackage.removePermission(i);
1380                         }
1381                     } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) {
1382                         // Prevent apps to change protection level to dangerous from any other
1383                         // type as this would allow a privilege escalation where an app adds a
1384                         // normal/signature permission in other app's group and later redefines
1385                         // it as dangerous leading to the group auto-grant.
1386                         if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE)
1387                                 == PermissionInfo.PROTECTION_DANGEROUS) {
1388                             if (bp != null && !bp.isRuntime()) {
1389                                 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
1390                                         + " trying to change a non-runtime permission "
1391                                         + perm.getName()
1392                                         + " to runtime; keeping old protection level");
1393                                 ComponentMutateUtils.setProtectionLevel(perm,
1394                                         bp.getProtectionLevel());
1395                             }
1396                         }
1397                     }
1398                 }
1399 
1400                 if (perm.getGroup() != null
1401                         && cannotInstallWithBadPermissionGroups(parsedPackage)) {
1402                     boolean isPermGroupDefinedByPackage = false;
1403                     for (int groupNum = 0; groupNum < numGroups; groupNum++) {
1404                         if (parsedPackage.getPermissionGroups().get(groupNum).getName()
1405                                 .equals(perm.getGroup())) {
1406                             isPermGroupDefinedByPackage = true;
1407                             break;
1408                         }
1409                     }
1410 
1411                     if (!isPermGroupDefinedByPackage) {
1412                         final PermissionGroupInfo sourceGroup =
1413                                 mPm.getPermissionGroupInfo(perm.getGroup(), 0);
1414 
1415                         if (sourceGroup == null) {
1416                             EventLog.writeEvent(0x534e4554, "146211400", -1,
1417                                     parsedPackage.getPackageName());
1418 
1419                             throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP,
1420                                     "Package "
1421                                             + parsedPackage.getPackageName()
1422                                             + " attempting to declare permission "
1423                                             + perm.getName() + " in non-existing group "
1424                                             + perm.getGroup());
1425                         } else {
1426                             String groupSourcePackageName = sourceGroup.packageName;
1427 
1428                             if (!PLATFORM_PACKAGE_NAME.equals(groupSourcePackageName)
1429                                     && !doesSignatureMatchForPermissions(groupSourcePackageName,
1430                                     parsedPackage, scanFlags)) {
1431                                 EventLog.writeEvent(0x534e4554, "146211400", -1,
1432                                         parsedPackage.getPackageName());
1433 
1434                                 throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP,
1435                                         "Package "
1436                                                 + parsedPackage.getPackageName()
1437                                                 + " attempting to declare permission "
1438                                                 + perm.getName() + " in group "
1439                                                 + perm.getGroup() + " owned by package "
1440                                                 + groupSourcePackageName
1441                                                 + " with incompatible certificate");
1442                             }
1443                         }
1444                     }
1445                 }
1446             }
1447         }
1448 
1449         if (systemApp) {
1450             if (onExternal) {
1451                 // Abort update; system app can't be replaced with app on sdcard
1452                 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1453                         "Cannot install updates to system apps on sdcard");
1454             } else if (instantApp) {
1455                 // Abort update; system app can't be replaced with an instant app
1456                 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
1457                         "Cannot update a system app with an instant app");
1458             }
1459         }
1460 
1461         if (args.mMoveInfo != null) {
1462             // We did an in-place move, so dex is ready to roll
1463             scanFlags |= SCAN_NO_DEX;
1464             scanFlags |= SCAN_MOVE;
1465 
1466             synchronized (mPm.mLock) {
1467                 final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
1468                 if (ps == null) {
1469                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
1470                             "Missing settings for moved package " + pkgName);
1471                 }
1472 
1473                 // We moved the entire application as-is, so bring over the
1474                 // previously derived ABI information.
1475                 parsedPackage.setPrimaryCpuAbi(ps.getPrimaryCpuAbi())
1476                         .setSecondaryCpuAbi(ps.getSecondaryCpuAbi());
1477             }
1478 
1479         } else {
1480             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
1481             scanFlags |= SCAN_NO_DEX;
1482 
1483             try {
1484                 PackageSetting pkgSetting;
1485                 AndroidPackage oldPackage;
1486                 synchronized (mPm.mLock) {
1487                     pkgSetting = mPm.mSettings.getPackageLPr(pkgName);
1488                     oldPackage = mPm.mPackages.get(pkgName);
1489                 }
1490                 boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null
1491                         && pkgSetting.getPkgState().isUpdatedSystemApp();
1492                 final String abiOverride = deriveAbiOverride(args.mAbiOverride);
1493                 boolean isUpdatedSystemAppInferred = oldPackage != null && oldPackage.isSystem();
1494                 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
1495                         derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage,
1496                         isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
1497                         abiOverride, ScanPackageUtils.getAppLib32InstallDir());
1498                 derivedAbi.first.applyTo(parsedPackage);
1499                 derivedAbi.second.applyTo(parsedPackage);
1500             } catch (PackageManagerException pme) {
1501                 Slog.e(TAG, "Error deriving application ABI", pme);
1502                 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
1503                         "Error deriving application ABI: " + pme.getMessage());
1504             }
1505         }
1506 
1507         if (!args.doRename(res.mReturnCode, parsedPackage)) {
1508             throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
1509         }
1510 
1511         try {
1512             setUpFsVerityIfPossible(parsedPackage);
1513         } catch (Installer.InstallerException | IOException | DigestException
1514                 | NoSuchAlgorithmException e) {
1515             throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
1516                     "Failed to set up verity: " + e);
1517         }
1518 
1519         final PackageFreezer freezer =
1520                 freezePackageForInstall(pkgName, installFlags, "installPackageLI");
1521         boolean shouldCloseFreezerBeforeReturn = true;
1522         try {
1523             final AndroidPackage oldPackage;
1524             String renamedPackage;
1525             boolean sysPkg = false;
1526             int targetScanFlags = scanFlags;
1527             int targetParseFlags = parseFlags;
1528             final PackageSetting ps;
1529             final PackageSetting disabledPs;
1530             final SharedUserSetting sharedUserSetting;
1531             if (replace) {
1532                 final String pkgName11 = parsedPackage.getPackageName();
1533                 synchronized (mPm.mLock) {
1534                     oldPackage = mPm.mPackages.get(pkgName11);
1535                 }
1536                 if (parsedPackage.isStaticSharedLibrary()) {
1537                     // Static libs have a synthetic package name containing the version
1538                     // and cannot be updated as an update would get a new package name,
1539                     // unless this is installed from adb which is useful for development.
1540                     if (oldPackage != null
1541                             && (installFlags & PackageManager.INSTALL_FROM_ADB) == 0) {
1542                         throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
1543                                 "Packages declaring "
1544                                         + "static-shared libs cannot be updated");
1545                     }
1546                 }
1547 
1548                 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
1549 
1550                 final int[] allUsers;
1551                 final int[] installedUsers;
1552                 final int[] uninstalledUsers;
1553 
1554                 synchronized (mPm.mLock) {
1555                     if (DEBUG_INSTALL) {
1556                         Slog.d(TAG,
1557                                 "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
1558                     }
1559 
1560                     ps = mPm.mSettings.getPackageLPr(pkgName11);
1561                     disabledPs = mPm.mSettings.getDisabledSystemPkgLPr(ps);
1562                     sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(ps);
1563 
1564                     // verify signatures are valid
1565                     final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
1566                     if (ksms.shouldCheckUpgradeKeySetLocked(ps, sharedUserSetting, scanFlags)) {
1567                         if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) {
1568                             throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
1569                                     "New package not signed by keys specified by upgrade-keysets: "
1570                                             + pkgName11);
1571                         }
1572                     } else {
1573                         SigningDetails parsedPkgSigningDetails = parsedPackage.getSigningDetails();
1574                         SigningDetails oldPkgSigningDetails = oldPackage.getSigningDetails();
1575                         // default to original signature matching
1576                         if (!parsedPkgSigningDetails.checkCapability(oldPkgSigningDetails,
1577                                 SigningDetails.CertCapabilities.INSTALLED_DATA)
1578                                 && !oldPkgSigningDetails.checkCapability(parsedPkgSigningDetails,
1579                                 SigningDetails.CertCapabilities.ROLLBACK)) {
1580                             // Allow the update to proceed if this is a rollback and the parsed
1581                             // package's current signing key is the current signer or in the lineage
1582                             // of the old package; this allows a rollback to a previously installed
1583                             // version after an app's signing key has been rotated without requiring
1584                             // the rollback capability on the previous signing key.
1585                             if (!isRollback || !oldPkgSigningDetails.hasAncestorOrSelf(
1586                                     parsedPkgSigningDetails)) {
1587                                 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
1588                                         "New package has a different signature: " + pkgName11);
1589                             }
1590                         }
1591                     }
1592 
1593                     // don't allow a system upgrade unless the upgrade hash matches
1594                     if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) {
1595                         final byte[] digestBytes;
1596                         try {
1597                             final MessageDigest digest = MessageDigest.getInstance("SHA-512");
1598                             updateDigest(digest, new File(parsedPackage.getBaseApkPath()));
1599                             if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) {
1600                                 for (String path : parsedPackage.getSplitCodePaths()) {
1601                                     updateDigest(digest, new File(path));
1602                                 }
1603                             }
1604                             digestBytes = digest.digest();
1605                         } catch (NoSuchAlgorithmException | IOException e) {
1606                             throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
1607                                     "Could not compute hash: " + pkgName11);
1608                         }
1609                         if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) {
1610                             throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
1611                                     "New package fails restrict-update check: " + pkgName11);
1612                         }
1613                         // retain upgrade restriction
1614                         parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash());
1615                     }
1616 
1617                     // APK should not change its sharedUserId declarations
1618                     final var oldSharedUid = oldPackage.getSharedUserId() != null
1619                             ? oldPackage.getSharedUserId() : "<nothing>";
1620                     final var newSharedUid = parsedPackage.getSharedUserId() != null
1621                             ? parsedPackage.getSharedUserId() : "<nothing>";
1622                     if (!oldSharedUid.equals(newSharedUid)) {
1623                         throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED,
1624                                 "Package " + parsedPackage.getPackageName()
1625                                         + " shared user changed from "
1626                                         + oldSharedUid + " to " + newSharedUid);
1627                     }
1628 
1629                     // APK should not re-join shared UID
1630                     if (oldPackage.isLeavingSharedUid() && !parsedPackage.isLeavingSharedUid()) {
1631                         throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED,
1632                                 "Package " + parsedPackage.getPackageName()
1633                                         + " attempting to rejoin " + newSharedUid);
1634                     }
1635 
1636                     // In case of rollback, remember per-user/profile install state
1637                     allUsers = mPm.mUserManager.getUserIds();
1638                     installedUsers = ps.queryInstalledUsers(allUsers, true);
1639                     uninstalledUsers = ps.queryInstalledUsers(allUsers, false);
1640 
1641 
1642                     // don't allow an upgrade from full to ephemeral
1643                     if (isInstantApp) {
1644                         if (args.mUser == null
1645                                 || args.mUser.getIdentifier() == UserHandle.USER_ALL) {
1646                             for (int currentUser : allUsers) {
1647                                 if (!ps.getInstantApp(currentUser)) {
1648                                     // can't downgrade from full to instant
1649                                     Slog.w(TAG,
1650                                             "Can't replace full app with instant app: " + pkgName11
1651                                                     + " for user: " + currentUser);
1652                                     throw new PrepareFailure(
1653                                             PackageManager.INSTALL_FAILED_SESSION_INVALID);
1654                                 }
1655                             }
1656                         } else if (!ps.getInstantApp(args.mUser.getIdentifier())) {
1657                             // can't downgrade from full to instant
1658                             Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11
1659                                     + " for user: " + args.mUser.getIdentifier());
1660                             throw new PrepareFailure(
1661                                     PackageManager.INSTALL_FAILED_SESSION_INVALID);
1662                         }
1663                     }
1664                 }
1665 
1666                 // Update what is removed
1667                 res.mRemovedInfo = new PackageRemovedInfo(mPm);
1668                 res.mRemovedInfo.mUid = oldPackage.getUid();
1669                 res.mRemovedInfo.mRemovedPackage = oldPackage.getPackageName();
1670                 res.mRemovedInfo.mInstallerPackageName = ps.getInstallSource().installerPackageName;
1671                 res.mRemovedInfo.mIsStaticSharedLib =
1672                         parsedPackage.getStaticSharedLibName() != null;
1673                 res.mRemovedInfo.mIsUpdate = true;
1674                 res.mRemovedInfo.mOrigUsers = installedUsers;
1675                 res.mRemovedInfo.mInstallReasons = new SparseArray<>(installedUsers.length);
1676                 for (int i = 0; i < installedUsers.length; i++) {
1677                     final int userId = installedUsers[i];
1678                     res.mRemovedInfo.mInstallReasons.put(userId, ps.getInstallReason(userId));
1679                 }
1680                 res.mRemovedInfo.mUninstallReasons = new SparseArray<>(uninstalledUsers.length);
1681                 for (int i = 0; i < uninstalledUsers.length; i++) {
1682                     final int userId = uninstalledUsers[i];
1683                     res.mRemovedInfo.mUninstallReasons.put(userId, ps.getUninstallReason(userId));
1684                 }
1685                 res.mRemovedInfo.mIsExternal = oldPackage.isExternalStorage();
1686 
1687                 sysPkg = oldPackage.isSystem();
1688                 if (sysPkg) {
1689                     // Set the system/privileged/oem/vendor/product flags as needed
1690                     final boolean privileged = oldPackage.isPrivileged();
1691                     final boolean oem = oldPackage.isOem();
1692                     final boolean vendor = oldPackage.isVendor();
1693                     final boolean product = oldPackage.isProduct();
1694                     final boolean odm = oldPackage.isOdm();
1695                     final boolean systemExt = oldPackage.isSystemExt();
1696                     final @ParsingPackageUtils.ParseFlags int systemParseFlags = parseFlags;
1697                     final @PackageManagerService.ScanFlags int systemScanFlags = scanFlags
1698                             | SCAN_AS_SYSTEM
1699                             | (privileged ? SCAN_AS_PRIVILEGED : 0)
1700                             | (oem ? SCAN_AS_OEM : 0)
1701                             | (vendor ? SCAN_AS_VENDOR : 0)
1702                             | (product ? SCAN_AS_PRODUCT : 0)
1703                             | (odm ? SCAN_AS_ODM : 0)
1704                             | (systemExt ? SCAN_AS_SYSTEM_EXT : 0);
1705 
1706                     if (DEBUG_INSTALL) {
1707                         Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
1708                                 + ", old=" + oldPackage);
1709                     }
1710                     res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
1711                     targetParseFlags = systemParseFlags;
1712                     targetScanFlags = systemScanFlags;
1713                 } else { // non system replace
1714                     replace = true;
1715                     if (DEBUG_INSTALL) {
1716                         Slog.d(TAG,
1717                                 "replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
1718                                         + oldPackage);
1719                     }
1720                 }
1721             } else { // new package install
1722                 ps = null;
1723                 disabledPs = null;
1724                 replace = false;
1725                 oldPackage = null;
1726                 // Remember this for later, in case we need to rollback this install
1727                 String pkgName1 = parsedPackage.getPackageName();
1728 
1729                 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage);
1730 
1731                 // TODO(b/194319951): MOVE TO RECONCILE
1732                 synchronized (mPm.mLock) {
1733                     renamedPackage = mPm.mSettings.getRenamedPackageLPr(pkgName1);
1734                     if (renamedPackage != null) {
1735                         // A package with the same name is already installed, though
1736                         // it has been renamed to an older name.  The package we
1737                         // are trying to install should be installed as an update to
1738                         // the existing one, but that has not been requested, so bail.
1739                         throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
1740                                 "Attempt to re-install " + pkgName1
1741                                         + " without first uninstalling package running as "
1742                                         + renamedPackage);
1743                     }
1744                     if (mPm.mPackages.containsKey(pkgName1)) {
1745                         // Don't allow installation over an existing package with the same name.
1746                         throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
1747                                 "Attempt to re-install " + pkgName1
1748                                         + " without first uninstalling.");
1749                     }
1750                 }
1751             }
1752             // we're passing the freezer back to be closed in a later phase of install
1753             shouldCloseFreezerBeforeReturn = false;
1754 
1755             return new PrepareResult(replace, targetScanFlags, targetParseFlags,
1756                     oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
1757                     ps, disabledPs);
1758         } finally {
1759             res.mFreezer = freezer;
1760             if (shouldCloseFreezerBeforeReturn) {
1761                 freezer.close();
1762             }
1763         }
1764     }
1765 
1766     /*
1767      * Cannot properly check CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS using CompatChanges
1768      * as this only works for packages that are installed
1769      *
1770      * TODO: Move logic for permission group compatibility into PermissionManagerService
1771      */
1772     @SuppressWarnings("AndroidFrameworkCompatChange")
cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage)1773     private static boolean cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage) {
1774         return parsedPackage.getTargetSdkVersion() >= Build.VERSION_CODES.S;
1775     }
1776 
doesSignatureMatchForPermissions(@onNull String sourcePackageName, @NonNull ParsedPackage parsedPackage, int scanFlags)1777     private boolean doesSignatureMatchForPermissions(@NonNull String sourcePackageName,
1778             @NonNull ParsedPackage parsedPackage, int scanFlags) {
1779         // If the defining package is signed with our cert, it's okay.  This
1780         // also includes the "updating the same package" case, of course.
1781         // "updating same package" could also involve key-rotation.
1782 
1783         final PackageSetting sourcePackageSetting;
1784         final KeySetManagerService ksms;
1785         final SharedUserSetting sharedUserSetting;
1786         synchronized (mPm.mLock) {
1787             sourcePackageSetting = mPm.mSettings.getPackageLPr(sourcePackageName);
1788             ksms = mPm.mSettings.getKeySetManagerService();
1789             sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(sourcePackageSetting);
1790         }
1791 
1792         final SigningDetails sourceSigningDetails = (sourcePackageSetting == null
1793                 ? SigningDetails.UNKNOWN : sourcePackageSetting.getSigningDetails());
1794         if (sourcePackageName.equals(parsedPackage.getPackageName())
1795                 && (ksms.shouldCheckUpgradeKeySetLocked(
1796                         sourcePackageSetting, sharedUserSetting, scanFlags))) {
1797             return ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage);
1798         } else {
1799 
1800             // in the event of signing certificate rotation, we need to see if the
1801             // package's certificate has rotated from the current one, or if it is an
1802             // older certificate with which the current is ok with sharing permissions
1803             if (sourceSigningDetails.checkCapability(
1804                     parsedPackage.getSigningDetails(),
1805                     SigningDetails.CertCapabilities.PERMISSION)) {
1806                 return true;
1807             } else if (parsedPackage.getSigningDetails().checkCapability(
1808                     sourceSigningDetails,
1809                     SigningDetails.CertCapabilities.PERMISSION)) {
1810                 // the scanned package checks out, has signing certificate rotation
1811                 // history, and is newer; bring it over
1812                 synchronized (mPm.mLock) {
1813                     sourcePackageSetting.setSigningDetails(parsedPackage.getSigningDetails());
1814                 }
1815                 return true;
1816             } else {
1817                 return false;
1818             }
1819         }
1820     }
1821 
1822     /**
1823      * Set up fs-verity for the given package if possible.  This requires a feature flag of system
1824      * property to be enabled only if the kernel supports fs-verity.
1825      *
1826      * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
1827      * kernel patches). In normal mode, all file format can be supported.
1828      */
setUpFsVerityIfPossible(AndroidPackage pkg)1829     private void setUpFsVerityIfPossible(AndroidPackage pkg) throws Installer.InstallerException,
1830             PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
1831         if (!PackageManagerServiceUtils.isApkVerityEnabled()) {
1832             return;
1833         }
1834 
1835         if (isIncrementalPath(pkg.getPath()) && IncrementalManager.getVersion()
1836                 < IncrementalManager.MIN_VERSION_TO_SUPPORT_FSVERITY) {
1837             return;
1838         }
1839 
1840         // Collect files we care for fs-verity setup.
1841         ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
1842         // NB: These files will become only accessible if the signing key is loaded in kernel's
1843         // .fs-verity keyring.
1844         fsverityCandidates.put(pkg.getBaseApkPath(),
1845                 VerityUtils.getFsveritySignatureFilePath(pkg.getBaseApkPath()));
1846 
1847         final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(
1848                 pkg.getBaseApkPath());
1849         if (new File(dmPath).exists()) {
1850             fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
1851         }
1852 
1853         for (String path : pkg.getSplitCodePaths()) {
1854             fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path));
1855 
1856             final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path);
1857             if (new File(splitDmPath).exists()) {
1858                 fsverityCandidates.put(splitDmPath,
1859                         VerityUtils.getFsveritySignatureFilePath(splitDmPath));
1860             }
1861         }
1862 
1863         final String packageName = pkg.getPackageName();
1864         for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
1865             final String filePath = entry.getKey();
1866             final String signaturePath = entry.getValue();
1867 
1868             // fs-verity is optional for now.  Only set up if signature is provided.
1869             if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) {
1870                 try {
1871                     VerityUtils.setUpFsverity(filePath, signaturePath);
1872                 } catch (IOException e) {
1873                     throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
1874                             "Failed to enable fs-verity: " + e);
1875                 }
1876             }
1877         }
1878     }
1879 
freezePackageForInstall(String packageName, int installFlags, String killReason)1880     private PackageFreezer freezePackageForInstall(String packageName, int installFlags,
1881             String killReason) {
1882         return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
1883     }
1884 
freezePackageForInstall(String packageName, int userId, int installFlags, String killReason)1885     private PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
1886             String killReason) {
1887         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
1888             return new PackageFreezer(mPm);
1889         } else {
1890             return mPm.freezePackage(packageName, userId, killReason);
1891         }
1892     }
1893 
updateDigest(MessageDigest digest, File file)1894     private static void updateDigest(MessageDigest digest, File file) throws IOException {
1895         try (DigestInputStream digestStream =
1896                      new DigestInputStream(new FileInputStream(file), digest)) {
1897             int length, total = 0;
1898             while ((length = digestStream.read()) != -1) {
1899                 total += length;
1900             } // just plow through the file
1901         }
1902     }
1903 
1904     @GuardedBy("mPm.mLock")
commitPackagesLocked(final CommitRequest request)1905     private void commitPackagesLocked(final CommitRequest request) {
1906         // TODO: remove any expected failures from this method; this should only be able to fail due
1907         //       to unavoidable errors (I/O, etc.)
1908         for (ReconciledPackage reconciledPkg : request.mReconciledPackages.values()) {
1909             final ScanResult scanResult = reconciledPkg.mScanResult;
1910             final ScanRequest scanRequest = scanResult.mRequest;
1911             final ParsedPackage parsedPackage = scanRequest.mParsedPackage;
1912             final String packageName = parsedPackage.getPackageName();
1913             final PackageInstalledInfo res = reconciledPkg.mInstallResult;
1914             final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
1915             final DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm);
1916 
1917             if (reconciledPkg.mPrepareResult.mReplace) {
1918                 AndroidPackage oldPackage = mPm.mPackages.get(packageName);
1919 
1920                 // Set the update and install times
1921                 PackageStateInternal deletedPkgSetting = mPm.snapshotComputer()
1922                         .getPackageStateInternal(oldPackage.getPackageName());
1923                 reconciledPkg.mPkgSetting
1924                         .setFirstInstallTimeFromReplaced(deletedPkgSetting, request.mAllUsers)
1925                         .setLastUpdateTime(System.currentTimeMillis());
1926 
1927                 res.mRemovedInfo.mBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(
1928                         mPm.snapshotComputer(), reconciledPkg.mPkgSetting, request.mAllUsers,
1929                         mPm.mSettings.getPackagesLocked());
1930                 if (reconciledPkg.mPrepareResult.mSystem) {
1931                     // Remove existing system package
1932                     removePackageHelper.removePackageLI(oldPackage, true);
1933                     if (!disableSystemPackageLPw(oldPackage)) {
1934                         // We didn't need to disable the .apk as a current system package,
1935                         // which means we are replacing another update that is already
1936                         // installed.  We need to make sure to delete the older one's .apk.
1937                         res.mRemovedInfo.mArgs = new FileInstallArgs(
1938                                 oldPackage.getPath(),
1939                                 getAppDexInstructionSets(
1940                                         AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
1941                                                 deletedPkgSetting),
1942                                         AndroidPackageUtils.getSecondaryCpuAbi(oldPackage,
1943                                                 deletedPkgSetting)), mPm);
1944                     } else {
1945                         res.mRemovedInfo.mArgs = null;
1946                     }
1947                 } else {
1948                     try {
1949                         // Settings will be written during the call to updateSettingsLI().
1950                         deletePackageHelper.executeDeletePackageLIF(
1951                                 reconciledPkg.mDeletePackageAction, packageName,
1952                                 true, request.mAllUsers, false);
1953                     } catch (SystemDeleteException e) {
1954                         if (mPm.mIsEngBuild) {
1955                             throw new RuntimeException("Unexpected failure", e);
1956                             // ignore; not possible for non-system app
1957                         }
1958                     }
1959                     // Successfully deleted the old package; proceed with replace.
1960                     // Update the in-memory copy of the previous code paths.
1961                     PackageSetting ps1 = mPm.mSettings.getPackageLPr(
1962                             reconciledPkg.mPrepareResult.mExistingPackage.getPackageName());
1963                     if ((reconciledPkg.mInstallArgs.mInstallFlags & PackageManager.DONT_KILL_APP)
1964                             == 0) {
1965                         Set<String> oldCodePaths = ps1.getOldCodePaths();
1966                         if (oldCodePaths == null) {
1967                             oldCodePaths = new ArraySet<>();
1968                         }
1969                         Collections.addAll(oldCodePaths, oldPackage.getBaseApkPath());
1970                         Collections.addAll(oldCodePaths, oldPackage.getSplitCodePaths());
1971                         ps1.setOldCodePaths(oldCodePaths);
1972                     } else {
1973                         ps1.setOldCodePaths(null);
1974                     }
1975 
1976                     if (reconciledPkg.mInstallResult.mReturnCode
1977                             == PackageManager.INSTALL_SUCCEEDED) {
1978                         PackageSetting ps2 = mPm.mSettings.getPackageLPr(
1979                                 parsedPackage.getPackageName());
1980                         if (ps2 != null) {
1981                             res.mRemovedInfo.mRemovedForAllUsers =
1982                                     mPm.mPackages.get(ps2.getPackageName()) == null;
1983                         }
1984                     }
1985                 }
1986             }
1987 
1988             AndroidPackage pkg = commitReconciledScanResultLocked(
1989                     reconciledPkg, request.mAllUsers);
1990             updateSettingsLI(pkg, reconciledPkg, request.mAllUsers, res);
1991 
1992             final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
1993             if (ps != null) {
1994                 res.mNewUsers = ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true);
1995                 ps.setUpdateAvailable(false /*updateAvailable*/);
1996             }
1997             if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED) {
1998                 mPm.updateSequenceNumberLP(ps, res.mNewUsers);
1999                 mPm.updateInstantAppInstallerLocked(packageName);
2000             }
2001         }
2002         ApplicationPackageManager.invalidateGetPackagesForUidCache();
2003     }
2004 
2005     @GuardedBy("mPm.mLock")
disableSystemPackageLPw(AndroidPackage oldPkg)2006     private boolean disableSystemPackageLPw(AndroidPackage oldPkg) {
2007         return mPm.mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true);
2008     }
2009 
updateSettingsLI(AndroidPackage newPackage, ReconciledPackage reconciledPkg, int[] allUsers, PackageInstalledInfo res)2010     private void updateSettingsLI(AndroidPackage newPackage, ReconciledPackage reconciledPkg,
2011             int[] allUsers, PackageInstalledInfo res) {
2012         updateSettingsInternalLI(newPackage, reconciledPkg, allUsers, res);
2013     }
2014 
updateSettingsInternalLI(AndroidPackage pkg, ReconciledPackage reconciledPkg, int[] allUsers, PackageInstalledInfo res)2015     private void updateSettingsInternalLI(AndroidPackage pkg, ReconciledPackage reconciledPkg,
2016             int[] allUsers, PackageInstalledInfo res) {
2017         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
2018 
2019         final String pkgName = pkg.getPackageName();
2020         final int[] installedForUsers = res.mOrigUsers;
2021         final InstallArgs installArgs = reconciledPkg.mInstallArgs;
2022         final int installReason = installArgs.mInstallReason;
2023         InstallSource installSource = installArgs.mInstallSource;
2024         final String installerPackageName = installSource.installerPackageName;
2025 
2026         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getPath());
2027         synchronized (mPm.mLock) {
2028             // For system-bundled packages, we assume that installing an upgraded version
2029             // of the package implies that the user actually wants to run that new code,
2030             // so we enable the package.
2031             final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
2032             final int userId = installArgs.mUser.getIdentifier();
2033             if (ps != null) {
2034                 if (pkg.isSystem()) {
2035                     if (DEBUG_INSTALL) {
2036                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
2037                     }
2038                     // Enable system package for requested users
2039                     if (res.mOrigUsers != null) {
2040                         for (int origUserId : res.mOrigUsers) {
2041                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
2042                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
2043                                         origUserId, installerPackageName);
2044                             }
2045                         }
2046                     }
2047                     // Also convey the prior install/uninstall state
2048                     if (allUsers != null && installedForUsers != null) {
2049                         for (int currentUserId : allUsers) {
2050                             final boolean installed = ArrayUtils.contains(
2051                                     installedForUsers, currentUserId);
2052                             if (DEBUG_INSTALL) {
2053                                 Slog.d(TAG, "    user " + currentUserId + " => " + installed);
2054                             }
2055                             ps.setInstalled(installed, currentUserId);
2056                         }
2057                         // these install state changes will be persisted in the
2058                         // upcoming call to mSettings.writeLPr().
2059                     }
2060 
2061                     if (allUsers != null) {
2062                         for (int currentUserId : allUsers) {
2063                             ps.resetOverrideComponentLabelIcon(currentUserId);
2064                         }
2065                     }
2066                 }
2067 
2068                 // Retrieve the overlays for shared libraries of the package.
2069                 if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) {
2070                     for (SharedLibraryInfo sharedLib : ps.getPkgState().getUsesLibraryInfos()) {
2071                         for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
2072                             if (!sharedLib.isDynamic()) {
2073                                 // TODO(146804378): Support overlaying static shared libraries
2074                                 continue;
2075                             }
2076                             final PackageSetting libPs = mPm.mSettings.getPackageLPr(
2077                                     sharedLib.getPackageName());
2078                             if (libPs == null) {
2079                                 continue;
2080                             }
2081                             ps.setOverlayPathsForLibrary(sharedLib.getName(),
2082                                     libPs.getOverlayPaths(currentUserId), currentUserId);
2083                         }
2084                     }
2085                 }
2086 
2087                 if (userId != UserHandle.USER_ALL) {
2088                     // It's implied that when a user requests installation, they want the app to
2089                     // be installed and enabled.
2090                     ps.setInstalled(true, userId);
2091                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
2092                 } else if (allUsers != null) {
2093                     // The caller explicitly specified INSTALL_ALL_USERS flag.
2094                     // Thus, updating the settings to install the app for all users.
2095                     for (int currentUserId : allUsers) {
2096                         // If the app is already installed for the currentUser,
2097                         // keep it as installed as we might be updating the app at this place.
2098                         // If not currently installed, check if the currentUser is restricted by
2099                         // DISALLOW_INSTALL_APPS or DISALLOW_DEBUGGING_FEATURES device policy.
2100                         // Install / update the app if the user isn't restricted. Skip otherwise.
2101                         final boolean installedForCurrentUser = ArrayUtils.contains(
2102                                 installedForUsers, currentUserId);
2103                         final boolean restrictedByPolicy =
2104                                 mPm.isUserRestricted(currentUserId,
2105                                         UserManager.DISALLOW_INSTALL_APPS)
2106                                 || mPm.isUserRestricted(currentUserId,
2107                                         UserManager.DISALLOW_DEBUGGING_FEATURES);
2108                         if (installedForCurrentUser || !restrictedByPolicy) {
2109                             ps.setInstalled(true, currentUserId);
2110                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId,
2111                                     installerPackageName);
2112                         } else {
2113                             ps.setInstalled(false, currentUserId);
2114                         }
2115                     }
2116                 }
2117 
2118                 mPm.mSettings.addInstallerPackageNames(ps.getInstallSource());
2119 
2120                 // When replacing an existing package, preserve the original install reason for all
2121                 // users that had the package installed before. Similarly for uninstall reasons.
2122                 final Set<Integer> previousUserIds = new ArraySet<>();
2123                 if (res.mRemovedInfo != null && res.mRemovedInfo.mInstallReasons != null) {
2124                     final int installReasonCount = res.mRemovedInfo.mInstallReasons.size();
2125                     for (int i = 0; i < installReasonCount; i++) {
2126                         final int previousUserId = res.mRemovedInfo.mInstallReasons.keyAt(i);
2127                         final int previousInstallReason =
2128                                 res.mRemovedInfo.mInstallReasons.valueAt(i);
2129                         ps.setInstallReason(previousInstallReason, previousUserId);
2130                         previousUserIds.add(previousUserId);
2131                     }
2132                 }
2133                 if (res.mRemovedInfo != null && res.mRemovedInfo.mUninstallReasons != null) {
2134                     for (int i = 0; i < res.mRemovedInfo.mUninstallReasons.size(); i++) {
2135                         final int previousUserId = res.mRemovedInfo.mUninstallReasons.keyAt(i);
2136                         final int previousReason = res.mRemovedInfo.mUninstallReasons.valueAt(i);
2137                         ps.setUninstallReason(previousReason, previousUserId);
2138                     }
2139                 }
2140 
2141                 // Set install reason for users that are having the package newly installed.
2142                 final int[] allUsersList = mPm.mUserManager.getUserIds();
2143                 if (userId == UserHandle.USER_ALL) {
2144                     for (int currentUserId : allUsersList) {
2145                         if (!previousUserIds.contains(currentUserId)
2146                                 && ps.getInstalled(currentUserId)) {
2147                             ps.setInstallReason(installReason, currentUserId);
2148                         }
2149                     }
2150                 } else if (!previousUserIds.contains(userId)) {
2151                     ps.setInstallReason(installReason, userId);
2152                 }
2153 
2154                 // TODO(b/169721400): generalize Incremental States and create a Callback object
2155                 // that can be used for all the packages.
2156                 final String codePath = ps.getPathString();
2157                 if (IncrementalManager.isIncrementalPath(codePath)
2158                         && mIncrementalManager != null) {
2159                     mIncrementalManager.registerLoadingProgressCallback(codePath,
2160                             new IncrementalProgressListener(ps.getPackageName(), mPm));
2161                 }
2162 
2163                 // Ensure that the uninstall reason is UNKNOWN for users with the package installed.
2164                 for (int currentUserId : allUsersList) {
2165                     if (ps.getInstalled(currentUserId)) {
2166                         ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, currentUserId);
2167                     }
2168                 }
2169 
2170                 mPm.mSettings.writeKernelMappingLPr(ps);
2171 
2172                 final PermissionManagerServiceInternal.PackageInstalledParams.Builder
2173                         permissionParamsBuilder =
2174                         new PermissionManagerServiceInternal.PackageInstalledParams.Builder();
2175                 final boolean grantPermissions = (installArgs.mInstallFlags
2176                         & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
2177                 if (grantPermissions) {
2178                     final List<String> grantedPermissions =
2179                             installArgs.mInstallGrantPermissions != null
2180                                     ? Arrays.asList(installArgs.mInstallGrantPermissions)
2181                                     : pkg.getRequestedPermissions();
2182                     permissionParamsBuilder.setGrantedPermissions(grantedPermissions);
2183                 }
2184                 final boolean allowlistAllRestrictedPermissions =
2185                         (installArgs.mInstallFlags
2186                                 & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0;
2187                 final List<String> allowlistedRestrictedPermissions =
2188                         allowlistAllRestrictedPermissions ? pkg.getRequestedPermissions()
2189                                 : installArgs.mAllowlistedRestrictedPermissions;
2190                 if (allowlistedRestrictedPermissions != null) {
2191                     permissionParamsBuilder.setAllowlistedRestrictedPermissions(
2192                             allowlistedRestrictedPermissions);
2193                 }
2194                 final int autoRevokePermissionsMode = installArgs.mAutoRevokePermissionsMode;
2195                 permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode);
2196                 final ScanResult scanResult = reconciledPkg.mScanResult;
2197                 mPm.mPermissionManager.onPackageInstalled(pkg, scanResult.mPreviousAppId,
2198                         permissionParamsBuilder.build(), userId);
2199                 // Apply restricted settings on potentially dangerous packages.
2200                 if (installArgs.mPackageSource == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE
2201                         || installArgs.mPackageSource
2202                         == PackageInstaller.PACKAGE_SOURCE_DOWNLOADED_FILE) {
2203                     enableRestrictedSettings(pkgName, pkg.getUid());
2204                 }
2205             }
2206             res.mName = pkgName;
2207             res.mUid = pkg.getUid();
2208             res.mPkg = pkg;
2209             res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
2210             //to update install status
2211             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
2212             mPm.writeSettingsLPrTEMP();
2213             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2214         }
2215 
2216         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2217     }
2218 
enableRestrictedSettings(String pkgName, int appId)2219     private void enableRestrictedSettings(String pkgName, int appId) {
2220         final AppOpsManager appOpsManager = mPm.mContext.getSystemService(AppOpsManager.class);
2221         final int[] allUsersList = mPm.mUserManager.getUserIds();
2222         for (int userId : allUsersList) {
2223             final int uid = UserHandle.getUid(userId, appId);
2224             appOpsManager.setMode(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
2225                     uid,
2226                     pkgName,
2227                     AppOpsManager.MODE_ERRORED);
2228         }
2229     }
2230 
2231     /**
2232      * On successful install, executes remaining steps after commit completes and the package lock
2233      * is released. These are typically more expensive or require calls to installd, which often
2234      * locks on {@link com.android.server.pm.PackageManagerService.mLock}.
2235      */
executePostCommitSteps(CommitRequest commitRequest)2236     private void executePostCommitSteps(CommitRequest commitRequest) {
2237         final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();
2238         for (ReconciledPackage reconciledPkg : commitRequest.mReconciledPackages.values()) {
2239             final boolean instantApp = ((reconciledPkg.mScanResult.mRequest.mScanFlags
2240                     & SCAN_AS_INSTANT_APP) != 0);
2241             final AndroidPackage pkg = reconciledPkg.mPkgSetting.getPkg();
2242             final String packageName = pkg.getPackageName();
2243             final String codePath = pkg.getPath();
2244             final boolean onIncremental = mIncrementalManager != null
2245                     && isIncrementalPath(codePath);
2246             if (onIncremental) {
2247                 IncrementalStorage storage = mIncrementalManager.openStorage(codePath);
2248                 if (storage == null) {
2249                     throw new IllegalArgumentException(
2250                             "Install: null storage for incremental package " + packageName);
2251                 }
2252                 incrementalStorages.add(storage);
2253             }
2254             // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
2255             mAppDataHelper.prepareAppDataPostCommitLIF(pkg, 0);
2256             if (reconciledPkg.mPrepareResult.mClearCodeCache) {
2257                 mAppDataHelper.clearAppDataLIF(pkg, UserHandle.USER_ALL,
2258                         FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
2259                                 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2260             }
2261             if (reconciledPkg.mPrepareResult.mReplace) {
2262                 mDexManager.notifyPackageUpdated(pkg.getPackageName(),
2263                         pkg.getBaseApkPath(), pkg.getSplitCodePaths());
2264             }
2265 
2266             // Prepare the application profiles for the new code paths.
2267             // This needs to be done before invoking dexopt so that any install-time profile
2268             // can be used for optimizations.
2269             mArtManagerService.prepareAppProfiles(
2270                     pkg,
2271                     mPm.resolveUserIds(reconciledPkg.mInstallArgs.mUser.getIdentifier()),
2272                     /* updateReferenceProfileContent= */ true);
2273 
2274             // Compute the compilation reason from the installation scenario.
2275             final int compilationReason =
2276                     mDexManager.getCompilationReasonForInstallScenario(
2277                             reconciledPkg.mInstallArgs.mInstallScenario);
2278 
2279             // Construct the DexoptOptions early to see if we should skip running dexopt.
2280             //
2281             // Do not run PackageDexOptimizer through the local performDexOpt
2282             // method because `pkg` may not be in `mPackages` yet.
2283             //
2284             // Also, don't fail application installs if the dexopt step fails.
2285             final boolean isBackupOrRestore =
2286                     reconciledPkg.mInstallArgs.mInstallReason == INSTALL_REASON_DEVICE_RESTORE
2287                             || reconciledPkg.mInstallArgs.mInstallReason
2288                             == INSTALL_REASON_DEVICE_SETUP;
2289 
2290             final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
2291                     | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE
2292                     | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);
2293             DexoptOptions dexoptOptions =
2294                     new DexoptOptions(packageName, compilationReason, dexoptFlags);
2295 
2296             // Check whether we need to dexopt the app.
2297             //
2298             // NOTE: it is IMPORTANT to call dexopt:
2299             //   - after doRename which will sync the package data from AndroidPackage and
2300             //     its corresponding ApplicationInfo.
2301             //   - after installNewPackageLIF or replacePackageLIF which will update result with the
2302             //     uid of the application (pkg.applicationInfo.uid).
2303             //     This update happens in place!
2304             //
2305             // We only need to dexopt if the package meets ALL of the following conditions:
2306             //   1) it is not an instant app or if it is then dexopt is enabled via gservices.
2307             //   2) it is not debuggable.
2308             //   3) it is not on Incremental File System.
2309             //
2310             // Note that we do not dexopt instant apps by default. dexopt can take some time to
2311             // complete, so we skip this step during installation. Instead, we'll take extra time
2312             // the first time the instant app starts. It's preferred to do it this way to provide
2313             // continuous progress to the useur instead of mysteriously blocking somewhere in the
2314             // middle of running an instant app. The default behaviour can be overridden
2315             // via gservices.
2316             //
2317             // Furthermore, dexopt may be skipped, depending on the install scenario and current
2318             // state of the device.
2319             //
2320             // TODO(b/174695087): instantApp and onIncremental should be removed and their install
2321             //       path moved to SCENARIO_FAST.
2322             final boolean performDexopt =
2323                     (!instantApp || android.provider.Settings.Global.getInt(
2324                             mContext.getContentResolver(),
2325                             android.provider.Settings.Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
2326                             && !pkg.isDebuggable()
2327                             && (!onIncremental)
2328                             && dexoptOptions.isCompilationEnabled();
2329 
2330             if (performDexopt) {
2331                 // Compile the layout resources.
2332                 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
2333                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
2334                     mViewCompiler.compileLayouts(pkg);
2335                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2336                 }
2337 
2338                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
2339                 ScanResult result = reconciledPkg.mScanResult;
2340 
2341                 // This mirrors logic from commitReconciledScanResultLocked, where the library files
2342                 // needed for dexopt are assigned.
2343                 // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous
2344                 //  setting needs to be passed to have a comparison, hide it behind an immutable
2345                 //  interface. There's no good reason to have 3 different ways to access the real
2346                 //  PackageSetting object, only one of which is actually correct.
2347                 PackageSetting realPkgSetting = result.mExistingSettingCopied
2348                         ? result.mRequest.mPkgSetting : result.mPkgSetting;
2349                 if (realPkgSetting == null) {
2350                     realPkgSetting = reconciledPkg.mPkgSetting;
2351                 }
2352 
2353                 // Unfortunately, the updated system app flag is only tracked on this PackageSetting
2354                 boolean isUpdatedSystemApp = reconciledPkg.mPkgSetting.getPkgState()
2355                         .isUpdatedSystemApp();
2356 
2357                 realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);
2358 
2359                 mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,
2360                         null /* instructionSets */,
2361                         mPm.getOrCreateCompilerPackageStats(pkg),
2362                         mDexManager.getPackageUseInfoOrDefault(packageName),
2363                         dexoptOptions);
2364                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2365             }
2366 
2367             // Notify BackgroundDexOptService that the package has been changed.
2368             // If this is an update of a package which used to fail to compile,
2369             // BackgroundDexOptService will remove it from its denylist.
2370             // TODO: Layering violation
2371             BackgroundDexOptService.getService().notifyPackageChanged(packageName);
2372 
2373             notifyPackageChangeObserversOnUpdate(reconciledPkg);
2374         }
2375         PackageManagerServiceUtils.waitForNativeBinariesExtractionForIncremental(
2376                 incrementalStorages);
2377     }
2378 
notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg)2379     private void notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg) {
2380         final PackageSetting pkgSetting = reconciledPkg.mPkgSetting;
2381         final PackageInstalledInfo pkgInstalledInfo = reconciledPkg.mInstallResult;
2382         final PackageRemovedInfo pkgRemovedInfo = pkgInstalledInfo.mRemovedInfo;
2383 
2384         PackageChangeEvent pkgChangeEvent = new PackageChangeEvent();
2385         pkgChangeEvent.packageName = pkgSetting.getPkg().getPackageName();
2386         pkgChangeEvent.version = pkgSetting.getVersionCode();
2387         pkgChangeEvent.lastUpdateTimeMillis = pkgSetting.getLastUpdateTime();
2388         pkgChangeEvent.newInstalled = (pkgRemovedInfo == null || !pkgRemovedInfo.mIsUpdate);
2389         pkgChangeEvent.dataRemoved = (pkgRemovedInfo != null && pkgRemovedInfo.mDataRemoved);
2390         pkgChangeEvent.isDeleted = false;
2391 
2392         mPm.notifyPackageChangeObservers(pkgChangeEvent);
2393     }
2394 
installLocationPolicy(PackageInfoLite pkgLite, int installFlags)2395     public int installLocationPolicy(PackageInfoLite pkgLite, int installFlags) {
2396         String packageName = pkgLite.packageName;
2397         int installLocation = pkgLite.installLocation;
2398         // reader
2399         synchronized (mPm.mLock) {
2400             // Currently installed package which the new package is attempting to replace or
2401             // null if no such package is installed.
2402             AndroidPackage installedPkg = mPm.mPackages.get(packageName);
2403 
2404             if (installedPkg != null) {
2405                 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
2406                     // Check for updated system application.
2407                     if (installedPkg.isSystem()) {
2408                         return InstallLocationUtils.RECOMMEND_INSTALL_INTERNAL;
2409                     } else {
2410                         // If current upgrade specifies particular preference
2411                         if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
2412                             // Application explicitly specified internal.
2413                             return InstallLocationUtils.RECOMMEND_INSTALL_INTERNAL;
2414                         } else if (
2415                                 installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
2416                             // App explicitly prefers external. Let policy decide
2417                         } else {
2418                             // Prefer previous location
2419                             if (installedPkg.isExternalStorage()) {
2420                                 return InstallLocationUtils.RECOMMEND_INSTALL_EXTERNAL;
2421                             }
2422                             return InstallLocationUtils.RECOMMEND_INSTALL_INTERNAL;
2423                         }
2424                     }
2425                 } else {
2426                     // Invalid install. Return error code
2427                     return InstallLocationUtils.RECOMMEND_FAILED_ALREADY_EXISTS;
2428                 }
2429             }
2430         }
2431         return pkgLite.recommendedInstallLocation;
2432     }
2433 
verifyReplacingVersionCode(PackageInfoLite pkgLite, long requiredInstalledVersionCode, int installFlags)2434     Pair<Integer, String> verifyReplacingVersionCode(PackageInfoLite pkgLite,
2435             long requiredInstalledVersionCode, int installFlags) {
2436         if ((installFlags & PackageManager.INSTALL_APEX) != 0) {
2437             return verifyReplacingVersionCodeForApex(
2438                     pkgLite, requiredInstalledVersionCode, installFlags);
2439         }
2440 
2441         String packageName = pkgLite.packageName;
2442         synchronized (mPm.mLock) {
2443             // Package which currently owns the data that the new package will own if installed.
2444             // If an app is uninstalled while keeping data (e.g. adb uninstall -k), installedPkg
2445             // will be null whereas dataOwnerPkg will contain information about the package
2446             // which was uninstalled while keeping its data.
2447             AndroidPackage dataOwnerPkg = mPm.mPackages.get(packageName);
2448             PackageSetting dataOwnerPs = mPm.mSettings.getPackageLPr(packageName);
2449             if (dataOwnerPkg  == null) {
2450                 if (dataOwnerPs != null) {
2451                     dataOwnerPkg = dataOwnerPs.getPkg();
2452                 }
2453             }
2454 
2455             if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
2456                 if (dataOwnerPkg == null) {
2457                     String errorMsg = "Required installed version code was "
2458                             + requiredInstalledVersionCode
2459                             + " but package is not installed";
2460                     Slog.w(TAG, errorMsg);
2461                     return Pair.create(
2462                             PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg);
2463                 }
2464 
2465                 if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
2466                     String errorMsg = "Required installed version code was "
2467                             + requiredInstalledVersionCode
2468                             + " but actual installed version is "
2469                             + dataOwnerPkg.getLongVersionCode();
2470                     Slog.w(TAG, errorMsg);
2471                     return Pair.create(
2472                             PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg);
2473                 }
2474             }
2475 
2476             if (dataOwnerPkg != null && !dataOwnerPkg.isSdkLibrary()) {
2477                 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
2478                         dataOwnerPkg.isDebuggable())) {
2479                     // Downgrade is not permitted; a lower version of the app will not be allowed
2480                     try {
2481                         PackageManagerServiceUtils.checkDowngrade(dataOwnerPkg, pkgLite);
2482                     } catch (PackageManagerException e) {
2483                         String errorMsg = "Downgrade detected: " + e.getMessage();
2484                         Slog.w(TAG, errorMsg);
2485                         return Pair.create(
2486                                 PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg);
2487                     }
2488                 } else if (dataOwnerPs.isSystem()) {
2489                     // Downgrade is permitted, but system apps can't be downgraded below
2490                     // the version preloaded onto the system image
2491                     final PackageSetting disabledPs = mPm.mSettings.getDisabledSystemPkgLPr(
2492                             dataOwnerPs);
2493                     if (disabledPs != null) {
2494                         dataOwnerPkg = disabledPs.getPkg();
2495                     }
2496                     if (!Build.IS_DEBUGGABLE && !dataOwnerPkg.isDebuggable()) {
2497                         // Only restrict non-debuggable builds and non-debuggable version of the app
2498                         try {
2499                             PackageManagerServiceUtils.checkDowngrade(dataOwnerPkg, pkgLite);
2500                         } catch (PackageManagerException e) {
2501                             String errorMsg =
2502                                     "System app: " + packageName + " cannot be downgraded to"
2503                                             + " older than its preloaded version on the system"
2504                                             + " image. " + e.getMessage();
2505                             Slog.w(TAG, errorMsg);
2506                             return Pair.create(
2507                                     PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg);
2508                         }
2509                     }
2510                 }
2511             }
2512         }
2513         return Pair.create(PackageManager.INSTALL_SUCCEEDED, null);
2514     }
2515 
verifyReplacingVersionCodeForApex(PackageInfoLite pkgLite, long requiredInstalledVersionCode, int installFlags)2516     private Pair<Integer, String> verifyReplacingVersionCodeForApex(PackageInfoLite pkgLite,
2517             long requiredInstalledVersionCode, int installFlags) {
2518         String packageName = pkgLite.packageName;
2519 
2520         final PackageInfo activePackage = mApexManager.getPackageInfo(packageName,
2521                 ApexManager.MATCH_ACTIVE_PACKAGE);
2522         if (activePackage == null) {
2523             String errorMsg = "Attempting to install new APEX package " + packageName;
2524             Slog.w(TAG, errorMsg);
2525             return Pair.create(PackageManager.INSTALL_FAILED_PACKAGE_CHANGED, errorMsg);
2526         }
2527 
2528         final long activeVersion = activePackage.getLongVersionCode();
2529         if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST
2530                 && activeVersion != requiredInstalledVersionCode) {
2531             String errorMsg = "Installed version of APEX package " + packageName
2532                     + " does not match required. Active version: " + activeVersion
2533                     + " required: " + requiredInstalledVersionCode;
2534             Slog.w(TAG, errorMsg);
2535             return Pair.create(PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg);
2536         }
2537 
2538         final boolean isAppDebuggable = (activePackage.applicationInfo.flags
2539                 & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
2540         final long newVersionCode = pkgLite.getLongVersionCode();
2541         if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags, isAppDebuggable)
2542                 && newVersionCode < activeVersion) {
2543             String errorMsg = "Downgrade of APEX package " + packageName
2544                     + " is not allowed. Active version: " + activeVersion
2545                     + " attempted: " + newVersionCode;
2546             Slog.w(TAG, errorMsg);
2547             return Pair.create(PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg);
2548         }
2549 
2550         return Pair.create(PackageManager.INSTALL_SUCCEEDED, null);
2551     }
2552 
getUidForVerifier(VerifierInfo verifierInfo)2553     int getUidForVerifier(VerifierInfo verifierInfo) {
2554         synchronized (mPm.mLock) {
2555             final AndroidPackage pkg = mPm.mPackages.get(verifierInfo.packageName);
2556             if (pkg == null) {
2557                 return -1;
2558             } else if (pkg.getSigningDetails().getSignatures().length != 1) {
2559                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
2560                         + " has more than one signature; ignoring");
2561                 return -1;
2562             }
2563 
2564             /*
2565              * If the public key of the package's signature does not match
2566              * our expected public key, then this is a different package and
2567              * we should skip.
2568              */
2569 
2570             final byte[] expectedPublicKey;
2571             try {
2572                 final Signature verifierSig = pkg.getSigningDetails().getSignatures()[0];
2573                 final PublicKey publicKey = verifierSig.getPublicKey();
2574                 expectedPublicKey = publicKey.getEncoded();
2575             } catch (CertificateException e) {
2576                 return -1;
2577             }
2578 
2579             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
2580 
2581             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
2582                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
2583                         + " does not have the expected public key; ignoring");
2584                 return -1;
2585             }
2586 
2587             return pkg.getUid();
2588         }
2589     }
2590 
sendPendingBroadcasts()2591     public void sendPendingBroadcasts() {
2592         String[] packages;
2593         ArrayList<String>[] components;
2594         int numBroadcasts = 0, numUsers;
2595         int[] uids;
2596 
2597         synchronized (mPm.mLock) {
2598             final SparseArray<ArrayMap<String, ArrayList<String>>> userIdToPackagesToComponents =
2599                     mPm.mPendingBroadcasts.copiedMap();
2600             numUsers = userIdToPackagesToComponents.size();
2601             for (int n = 0; n < numUsers; n++) {
2602                 numBroadcasts += userIdToPackagesToComponents.valueAt(n).size();
2603             }
2604             if (numBroadcasts == 0) {
2605                 // Nothing to be done. Just return
2606                 return;
2607             }
2608             packages = new String[numBroadcasts];
2609             components = new ArrayList[numBroadcasts];
2610             uids = new int[numBroadcasts];
2611             int i = 0;  // filling out the above arrays
2612 
2613             for (int n = 0; n < numUsers; n++) {
2614                 final int packageUserId = userIdToPackagesToComponents.keyAt(n);
2615                 final ArrayMap<String, ArrayList<String>> componentsToBroadcast =
2616                         userIdToPackagesToComponents.valueAt(n);
2617                 final int numComponents = CollectionUtils.size(componentsToBroadcast);
2618                 for (int index = 0; index < numComponents; index++) {
2619                     packages[i] = componentsToBroadcast.keyAt(index);
2620                     components[i] = componentsToBroadcast.valueAt(index);
2621                     final PackageSetting ps = mPm.mSettings.getPackageLPr(packages[i]);
2622                     uids[i] = (ps != null)
2623                             ? UserHandle.getUid(packageUserId, ps.getAppId())
2624                             : -1;
2625                     i++;
2626                 }
2627             }
2628             numBroadcasts = i;
2629             mPm.mPendingBroadcasts.clear();
2630         }
2631         final Computer snapshot = mPm.snapshotComputer();
2632         // Send broadcasts
2633         for (int i = 0; i < numBroadcasts; i++) {
2634             mPm.sendPackageChangedBroadcast(snapshot, packages[i], true /* dontKillApp */,
2635                     components[i], uids[i], null /* reason */);
2636         }
2637     }
2638 
handlePackagePostInstall(PackageInstalledInfo res, InstallArgs installArgs, boolean launchedForRestore)2639     void handlePackagePostInstall(PackageInstalledInfo res, InstallArgs installArgs,
2640             boolean launchedForRestore) {
2641         final boolean killApp =
2642                 (installArgs.mInstallFlags & PackageManager.INSTALL_DONT_KILL_APP) == 0;
2643         final boolean virtualPreload =
2644                 ((installArgs.mInstallFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
2645         final String installerPackage = installArgs.mInstallSource.installerPackageName;
2646         final IPackageInstallObserver2 installObserver = installArgs.mObserver;
2647         final int dataLoaderType = installArgs.mDataLoaderType;
2648         final boolean succeeded = res.mReturnCode == PackageManager.INSTALL_SUCCEEDED;
2649         final boolean update = res.mRemovedInfo != null && res.mRemovedInfo.mRemovedPackage != null;
2650         final String packageName = res.mName;
2651         final PackageStateInternal pkgSetting =
2652                 succeeded ? mPm.snapshotComputer().getPackageStateInternal(packageName) : null;
2653         final boolean removedBeforeUpdate = (pkgSetting == null)
2654                 || (pkgSetting.isSystem() && !pkgSetting.getPath().getPath().equals(
2655                 res.mPkg.getPath()));
2656         if (succeeded && removedBeforeUpdate) {
2657             Slog.e(TAG, packageName + " was removed before handlePackagePostInstall "
2658                     + "could be executed");
2659             res.mReturnCode = INSTALL_FAILED_PACKAGE_CHANGED;
2660             res.mReturnMsg = "Package was removed before install could complete.";
2661 
2662             // Remove the update failed package's older resources safely now
2663             InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null;
2664             if (args != null) {
2665                 synchronized (mPm.mInstallLock) {
2666                     args.doPostDeleteLI(true);
2667                 }
2668             }
2669             mPm.notifyInstallObserver(res, installObserver);
2670             return;
2671         }
2672 
2673         if (succeeded) {
2674             // Clear the uid cache after we installed a new package.
2675             mPm.mPerUidReadTimeoutsCache = null;
2676 
2677             // Send the removed broadcasts
2678             if (res.mRemovedInfo != null) {
2679                 if (res.mRemovedInfo.mIsExternal) {
2680                     if (DEBUG_INSTALL) {
2681                         Slog.i(TAG, "upgrading pkg " + res.mRemovedInfo.mRemovedPackage
2682                                 + " is ASEC-hosted -> UNAVAILABLE");
2683                     }
2684                     final int[] uidArray = new int[]{res.mRemovedInfo.mUid};
2685                     final ArrayList<String> pkgList = new ArrayList<>(1);
2686                     pkgList.add(res.mRemovedInfo.mRemovedPackage);
2687                     mBroadcastHelper.sendResourcesChangedBroadcast(
2688                             false, true, pkgList, uidArray, null);
2689                 }
2690                 res.mRemovedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/);
2691             }
2692 
2693             final String installerPackageName =
2694                     res.mInstallerPackageName != null
2695                             ? res.mInstallerPackageName
2696                             : res.mRemovedInfo != null
2697                                     ? res.mRemovedInfo.mInstallerPackageName
2698                                     : null;
2699 
2700             mPm.notifyInstantAppPackageInstalled(res.mPkg.getPackageName(), res.mNewUsers);
2701 
2702             // Determine the set of users who are adding this package for
2703             // the first time vs. those who are seeing an update.
2704             int[] firstUserIds = EMPTY_INT_ARRAY;
2705             int[] firstInstantUserIds = EMPTY_INT_ARRAY;
2706             int[] updateUserIds = EMPTY_INT_ARRAY;
2707             int[] instantUserIds = EMPTY_INT_ARRAY;
2708             final boolean allNewUsers = res.mOrigUsers == null || res.mOrigUsers.length == 0;
2709             for (int newUser : res.mNewUsers) {
2710                 final boolean isInstantApp = pkgSetting.getUserStateOrDefault(newUser)
2711                         .isInstantApp();
2712                 if (allNewUsers) {
2713                     if (isInstantApp) {
2714                         firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2715                     } else {
2716                         firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2717                     }
2718                     continue;
2719                 }
2720                 boolean isNew = true;
2721                 for (int origUser : res.mOrigUsers) {
2722                     if (origUser == newUser) {
2723                         isNew = false;
2724                         break;
2725                     }
2726                 }
2727                 if (isNew) {
2728                     if (isInstantApp) {
2729                         firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2730                     } else {
2731                         firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2732                     }
2733                 } else {
2734                     if (isInstantApp) {
2735                         instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2736                     } else {
2737                         updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2738                     }
2739                 }
2740             }
2741 
2742             // Send installed broadcasts if the package is not a static shared lib.
2743             if (res.mPkg.getStaticSharedLibName() == null) {
2744                 mPm.mProcessLoggingHandler.invalidateBaseApkHash(res.mPkg.getBaseApkPath());
2745 
2746                 // Send added for users that see the package for the first time
2747                 // sendPackageAddedForNewUsers also deals with system apps
2748                 int appId = UserHandle.getAppId(res.mUid);
2749                 boolean isSystem = res.mPkg.isSystem();
2750                 mPm.sendPackageAddedForNewUsers(mPm.snapshotComputer(), packageName,
2751                         isSystem || virtualPreload, virtualPreload /*startReceiver*/, appId,
2752                         firstUserIds, firstInstantUserIds, dataLoaderType);
2753 
2754                 // Send added for users that don't see the package for the first time
2755                 Bundle extras = new Bundle();
2756                 extras.putInt(Intent.EXTRA_UID, res.mUid);
2757                 if (update) {
2758                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
2759                 }
2760                 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
2761                 // Send to all running apps.
2762                 final SparseArray<int[]> newBroadcastAllowList;
2763                 synchronized (mPm.mLock) {
2764                     final Computer snapshot = mPm.snapshotComputer();
2765                     newBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(snapshot,
2766                             snapshot.getPackageStateInternal(packageName, Process.SYSTEM_UID),
2767                             updateUserIds, mPm.mSettings.getPackagesLocked());
2768                 }
2769                 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2770                         extras, 0 /*flags*/,
2771                         null /*targetPackage*/, null /*finishedReceiver*/,
2772                         updateUserIds, instantUserIds, newBroadcastAllowList, null);
2773                 if (installerPackageName != null) {
2774                     // Send to the installer, even if it's not running.
2775                     mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2776                             extras, 0 /*flags*/,
2777                             installerPackageName, null /*finishedReceiver*/,
2778                             updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
2779                 }
2780                 // if the required verifier is defined, but, is not the installer of record
2781                 // for the package, it gets notified
2782                 final boolean notifyVerifier = mPm.mRequiredVerifierPackage != null
2783                         && !mPm.mRequiredVerifierPackage.equals(installerPackageName);
2784                 if (notifyVerifier) {
2785                     mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2786                             extras, 0 /*flags*/,
2787                             mPm.mRequiredVerifierPackage, null /*finishedReceiver*/,
2788                             updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
2789                 }
2790                 // If package installer is defined, notify package installer about new
2791                 // app installed
2792                 if (mPm.mRequiredInstallerPackage != null) {
2793                     mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2794                             extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
2795                             mPm.mRequiredInstallerPackage, null /*finishedReceiver*/,
2796                             firstUserIds, instantUserIds, null /* broadcastAllowList */, null);
2797                 }
2798 
2799                 // Send replaced for users that don't see the package for the first time
2800                 if (update) {
2801                     mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2802                             packageName, extras, 0 /*flags*/,
2803                             null /*targetPackage*/, null /*finishedReceiver*/,
2804                             updateUserIds, instantUserIds, res.mRemovedInfo.mBroadcastAllowList,
2805                             null);
2806                     if (installerPackageName != null) {
2807                         mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2808                                 extras, 0 /*flags*/,
2809                                 installerPackageName, null /*finishedReceiver*/,
2810                                 updateUserIds, instantUserIds, null /*broadcastAllowList*/,
2811                                 null);
2812                     }
2813                     if (notifyVerifier) {
2814                         mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2815                                 extras, 0 /*flags*/,
2816                                 mPm.mRequiredVerifierPackage, null /*finishedReceiver*/,
2817                                 updateUserIds, instantUserIds, null /*broadcastAllowList*/,
2818                                 null);
2819                     }
2820                     mPm.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2821                             null /*package*/, null /*extras*/, 0 /*flags*/,
2822                             packageName /*targetPackage*/,
2823                             null /*finishedReceiver*/, updateUserIds, instantUserIds,
2824                             null /*broadcastAllowList*/,
2825                             mBroadcastHelper.getTemporaryAppAllowlistBroadcastOptions(
2826                                     REASON_PACKAGE_REPLACED).toBundle());
2827                 } else if (launchedForRestore && !res.mPkg.isSystem()) {
2828                     // First-install and we did a restore, so we're responsible for the
2829                     // first-launch broadcast.
2830                     if (DEBUG_BACKUP) {
2831                         Slog.i(TAG, "Post-restore of " + packageName
2832                                 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2833                     }
2834                     mBroadcastHelper.sendFirstLaunchBroadcast(packageName, installerPackage,
2835                             firstUserIds, firstInstantUserIds);
2836                 }
2837 
2838                 // Send broadcast package appeared if external for all users
2839                 if (res.mPkg.isExternalStorage()) {
2840                     if (!update) {
2841                         final StorageManager storageManager =
2842                                 mInjector.getSystemService(StorageManager.class);
2843                         VolumeInfo volume =
2844                                 storageManager.findVolumeByUuid(
2845                                         StorageManager.convert(
2846                                                 res.mPkg.getVolumeUuid()).toString());
2847                         int packageExternalStorageType =
2848                                 PackageManagerServiceUtils.getPackageExternalStorageType(volume,
2849                                         res.mPkg.isExternalStorage());
2850                         // If the package was installed externally, log it.
2851                         if (packageExternalStorageType != StorageEnums.UNKNOWN) {
2852                             FrameworkStatsLog.write(
2853                                     FrameworkStatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
2854                                     packageExternalStorageType, packageName);
2855                         }
2856                     }
2857                     if (DEBUG_INSTALL) {
2858                         Slog.i(TAG, "upgrading pkg " + res.mPkg + " is external");
2859                     }
2860                     final int[] uidArray = new int[]{res.mPkg.getUid()};
2861                     ArrayList<String> pkgList = new ArrayList<>(1);
2862                     pkgList.add(packageName);
2863                     mBroadcastHelper.sendResourcesChangedBroadcast(
2864                             true, true, pkgList, uidArray, null);
2865                 }
2866             } else if (!ArrayUtils.isEmpty(res.mLibraryConsumers)) { // if static shared lib
2867                 // No need to kill consumers if it's installation of new version static shared lib.
2868                 final Computer snapshot = mPm.snapshotComputer();
2869                 final boolean dontKillApp = !update && res.mPkg.getStaticSharedLibName() != null;
2870                 for (int i = 0; i < res.mLibraryConsumers.size(); i++) {
2871                     AndroidPackage pkg = res.mLibraryConsumers.get(i);
2872                     // send broadcast that all consumers of the static shared library have changed
2873                     mPm.sendPackageChangedBroadcast(snapshot, pkg.getPackageName(), dontKillApp,
2874                             new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
2875                             pkg.getUid(), null);
2876                 }
2877             }
2878 
2879             // Work that needs to happen on first install within each user
2880             if (firstUserIds.length > 0) {
2881                 for (int userId : firstUserIds) {
2882                     mPm.restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
2883                             userId);
2884                 }
2885             }
2886 
2887             if (allNewUsers && !update) {
2888                 mPm.notifyPackageAdded(packageName, res.mUid);
2889             } else {
2890                 mPm.notifyPackageChanged(packageName, res.mUid);
2891             }
2892 
2893             // Log current value of "unknown sources" setting
2894             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2895                     getUnknownSourcesSettings());
2896 
2897             // Remove the replaced package's older resources safely now
2898             InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null;
2899             if (args != null) {
2900                 if (!killApp) {
2901                     // If we didn't kill the app, defer the deletion of code/resource files, since
2902                     // they may still be in use by the running application. This mitigates problems
2903                     // in cases where resources or code is loaded by a new Activity before
2904                     // ApplicationInfo changes have propagated to all application threads.
2905                     mPm.scheduleDeferredNoKillPostDelete(args);
2906                 } else {
2907                     synchronized (mPm.mInstallLock) {
2908                         args.doPostDeleteLI(true);
2909                     }
2910                 }
2911             } else {
2912                 // Force a gc to clear up things. Ask for a background one, it's fine to go on
2913                 // and not block here.
2914                 VMRuntime.getRuntime().requestConcurrentGC();
2915             }
2916 
2917             final Computer snapshot = mPm.snapshotComputer();
2918             // Notify DexManager that the package was installed for new users.
2919             // The updated users should already be indexed and the package code paths
2920             // should not change.
2921             // Don't notify the manager for ephemeral apps as they are not expected to
2922             // survive long enough to benefit of background optimizations.
2923             for (int userId : firstUserIds) {
2924                 PackageInfo info = snapshot.getPackageInfo(packageName, /*flags*/ 0, userId);
2925                 // There's a race currently where some install events may interleave with an
2926                 // uninstall. This can lead to package info being null (b/36642664).
2927                 if (info != null) {
2928                     mDexManager.notifyPackageInstalled(info, userId);
2929                 }
2930             }
2931         }
2932 
2933         final boolean deferInstallObserver = succeeded && update;
2934         if (deferInstallObserver) {
2935             if (killApp) {
2936                 mPm.scheduleDeferredPendingKillInstallObserver(res, installObserver);
2937             } else {
2938                 mPm.scheduleDeferredNoKillInstallObserver(res, installObserver);
2939             }
2940         } else {
2941             mPm.notifyInstallObserver(res, installObserver);
2942         }
2943 
2944         // Prune unused static shared libraries which have been cached a period of time
2945         mPm.schedulePruneUnusedStaticSharedLibraries(true /* delay */);
2946 
2947         // Log tracing if needed
2948         if (installArgs.mTraceMethod != null) {
2949             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, installArgs.mTraceMethod,
2950                     installArgs.mTraceCookie);
2951         }
2952     }
2953 
2954     /**
2955      * Get the "allow unknown sources" setting.
2956      *
2957      * @return the current "allow unknown sources" setting
2958      */
getUnknownSourcesSettings()2959     private int getUnknownSourcesSettings() {
2960         return android.provider.Settings.Secure.getIntForUser(mContext.getContentResolver(),
2961                 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
2962                 -1, UserHandle.USER_SYSTEM);
2963     }
2964 
2965     /**
2966      * Uncompress and install stub applications.
2967      * <p>In order to save space on the system partition, some applications are shipped in a
2968      * compressed form. In addition the compressed bits for the full application, the
2969      * system image contains a tiny stub comprised of only the Android manifest.
2970      * <p>During the first boot, attempt to uncompress and install the full application. If
2971      * the application can't be installed for any reason, disable the stub and prevent
2972      * uncompressing the full application during future boots.
2973      * <p>In order to forcefully attempt an installation of a full application, go to app
2974      * settings and enable the application.
2975      */
2976     @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
installSystemStubPackages(@onNull List<String> systemStubPackageNames, @PackageManagerService.ScanFlags int scanFlags)2977     void installSystemStubPackages(@NonNull List<String> systemStubPackageNames,
2978             @PackageManagerService.ScanFlags int scanFlags) {
2979         for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
2980             final String packageName = systemStubPackageNames.get(i);
2981             // skip if the system package is already disabled
2982             if (mPm.mSettings.isDisabledSystemPackageLPr(packageName)) {
2983                 systemStubPackageNames.remove(i);
2984                 continue;
2985             }
2986             // skip if the package isn't installed (?!); this should never happen
2987             final AndroidPackage pkg = mPm.mPackages.get(packageName);
2988             if (pkg == null) {
2989                 systemStubPackageNames.remove(i);
2990                 continue;
2991             }
2992             // skip if the package has been disabled by the user
2993             final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
2994             if (ps != null) {
2995                 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
2996                 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
2997                     systemStubPackageNames.remove(i);
2998                     continue;
2999                 }
3000             }
3001 
3002             // install the package to replace the stub on /system
3003             try {
3004                 installStubPackageLI(pkg, 0, scanFlags);
3005                 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3006                         UserHandle.USER_SYSTEM, "android");
3007                 systemStubPackageNames.remove(i);
3008             } catch (PackageManagerException e) {
3009                 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3010             }
3011 
3012             // any failed attempt to install the package will be cleaned up later
3013         }
3014 
3015         // disable any stub still left; these failed to install the full application
3016         for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
3017             final String pkgName = systemStubPackageNames.get(i);
3018             final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
3019             ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3020                     UserHandle.USER_SYSTEM, "android");
3021             logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3022         }
3023     }
3024 
3025     /**
3026      * Extract, install and enable a stub package.
3027      * <p>If the compressed file can not be extracted / installed for any reason, the stub
3028      * APK will be installed and the package will be disabled. To recover from this situation,
3029      * the user will need to go into system settings and re-enable the package.
3030      */
enableCompressedPackage(AndroidPackage stubPkg, @NonNull PackageSetting stubPkgSetting)3031     boolean enableCompressedPackage(AndroidPackage stubPkg,
3032             @NonNull PackageSetting stubPkgSetting) {
3033         final int parseFlags = mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_CHATTY
3034                 | ParsingPackageUtils.PARSE_ENFORCE_CODE;
3035         synchronized (mPm.mInstallLock) {
3036             final AndroidPackage pkg;
3037             try (PackageFreezer freezer =
3038                          mPm.freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
3039                 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
3040                 mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
3041                 synchronized (mPm.mLock) {
3042                     try {
3043                         mSharedLibraries.updateSharedLibrariesLPw(
3044                                 pkg, stubPkgSetting, null, null,
3045                                 Collections.unmodifiableMap(mPm.mPackages));
3046                     } catch (PackageManagerException e) {
3047                         Slog.w(TAG, "updateAllSharedLibrariesLPw failed: ", e);
3048                     }
3049                     mPm.mPermissionManager.onPackageInstalled(pkg,
3050                             Process.INVALID_UID /* previousAppId */,
3051                             PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
3052                             UserHandle.USER_ALL);
3053                     mPm.writeSettingsLPrTEMP();
3054                     // Since compressed package can be system app only, we do not need to
3055                     // set restricted settings on it.
3056                 }
3057             } catch (PackageManagerException e) {
3058                 // Whoops! Something went very wrong; roll back to the stub and disable the package
3059                 try (PackageFreezer freezer =
3060                              mPm.freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
3061                     synchronized (mPm.mLock) {
3062                         // NOTE: Ensure the system package is enabled; even for a compressed stub.
3063                         // If we don't, installing the system package fails during scan
3064                         mPm.mSettings.enableSystemPackageLPw(stubPkg.getPackageName());
3065                     }
3066                     installPackageFromSystemLIF(stubPkg.getPath(),
3067                             mPm.mUserManager.getUserIds() /*allUserHandles*/,
3068                             null /*origUserHandles*/,
3069                             true /*writeSettings*/);
3070                 } catch (PackageManagerException pme) {
3071                     // Serious WTF; we have to be able to install the stub
3072                     Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
3073                             pme);
3074                 } finally {
3075                     // Disable the package; the stub by itself is not runnable
3076                     synchronized (mPm.mLock) {
3077                         final PackageSetting stubPs = mPm.mSettings.getPackageLPr(
3078                                 stubPkg.getPackageName());
3079                         if (stubPs != null) {
3080                             stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED,
3081                                     UserHandle.USER_SYSTEM, "android");
3082                         }
3083                         mPm.writeSettingsLPrTEMP();
3084                     }
3085                 }
3086                 return false;
3087             }
3088             mAppDataHelper.clearAppDataLIF(pkg, UserHandle.USER_ALL,
3089                     FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
3090                             | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3091             mDexManager.notifyPackageUpdated(pkg.getPackageName(),
3092                     pkg.getBaseApkPath(), pkg.getSplitCodePaths());
3093         }
3094         return true;
3095     }
3096 
3097     @GuardedBy("mPm.mInstallLock")
installStubPackageLI(AndroidPackage stubPkg, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags)3098     private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
3099             @ParsingPackageUtils.ParseFlags int parseFlags,
3100             @PackageManagerService.ScanFlags int scanFlags)
3101             throws PackageManagerException {
3102         if (DEBUG_COMPRESSION) {
3103             Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName());
3104         }
3105         // uncompress the binary to its eventual destination on /data
3106         final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getPath());
3107         if (scanFile == null) {
3108             throw new PackageManagerException(
3109                     "Unable to decompress stub at " + stubPkg.getPath());
3110         }
3111         synchronized (mPm.mLock) {
3112             mPm.mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
3113         }
3114         final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
3115         removePackageHelper.removePackageLI(stubPkg, true /*chatty*/);
3116         try {
3117             return scanSystemPackageTracedLI(scanFile, parseFlags, scanFlags, null);
3118         } catch (PackageManagerException e) {
3119             Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
3120                     e);
3121             // Remove the failed install
3122             removePackageHelper.removeCodePathLI(scanFile);
3123             throw e;
3124         }
3125     }
3126 
3127     /**
3128      * Decompresses the given package on the system image onto
3129      * the /data partition.
3130      * @return The directory the package was decompressed into. Otherwise, {@code null}.
3131      */
3132     @GuardedBy("mPm.mInstallLock")
decompressPackage(String packageName, String codePath)3133     private File decompressPackage(String packageName, String codePath) {
3134         if (!compressedFileExists(codePath)) {
3135             if (DEBUG_COMPRESSION) {
3136                 Slog.i(TAG, "No files to decompress at: " + codePath);
3137             }
3138             return null;
3139         }
3140         final File dstCodePath =
3141                 PackageManagerServiceUtils.getNextCodePath(Environment.getDataAppDirectory(null),
3142                         packageName);
3143         int ret = PackageManagerServiceUtils.decompressFiles(codePath, dstCodePath, packageName);
3144         if (ret == PackageManager.INSTALL_SUCCEEDED) {
3145             ret = PackageManagerServiceUtils.extractNativeBinaries(dstCodePath, packageName);
3146         }
3147         if (ret == PackageManager.INSTALL_SUCCEEDED) {
3148             // NOTE: During boot, we have to delay releasing cblocks for no other reason than
3149             // we cannot retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}.
3150             // When we no longer need to read that setting, cblock release can occur always
3151             // occur here directly
3152             if (!mPm.isSystemReady()) {
3153                 if (mPm.mReleaseOnSystemReady == null) {
3154                     mPm.mReleaseOnSystemReady = new ArrayList<>();
3155                 }
3156                 mPm.mReleaseOnSystemReady.add(dstCodePath);
3157             } else {
3158                 final ContentResolver resolver = mContext.getContentResolver();
3159                 F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
3160             }
3161         } else {
3162             if (!dstCodePath.exists()) {
3163                 return null;
3164             }
3165             new RemovePackageHelper(mPm).removeCodePathLI(dstCodePath);
3166             return null;
3167         }
3168 
3169         return dstCodePath;
3170     }
3171 
3172     /**
3173      * Tries to restore the disabled system package after an update has been deleted.
3174      */
restoreDisabledSystemPackageLIF(DeletePackageAction action, @NonNull int[] allUserHandles, boolean writeSettings)3175     public void restoreDisabledSystemPackageLIF(DeletePackageAction action,
3176             @NonNull int[] allUserHandles, boolean writeSettings) throws SystemDeleteException {
3177         final PackageSetting deletedPs = action.mDeletingPs;
3178         final PackageRemovedInfo outInfo = action.mRemovedInfo;
3179         final PackageSetting disabledPs = action.mDisabledPs;
3180 
3181         synchronized (mPm.mLock) {
3182             // NOTE: The system package always needs to be enabled; even if it's for
3183             // a compressed stub. If we don't, installing the system package fails
3184             // during scan [scanning checks the disabled packages]. We will reverse
3185             // this later, after we've "installed" the stub.
3186             // Reinstate the old system package
3187             mPm.mSettings.enableSystemPackageLPw(disabledPs.getPkg().getPackageName());
3188             // Remove any native libraries from the upgraded package.
3189             PackageManagerServiceUtils.removeNativeBinariesLI(deletedPs);
3190         }
3191         // Install the system package
3192         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
3193         try {
3194             synchronized (mPm.mInstallLock) {
3195                 final int[] origUsers = outInfo == null ? null : outInfo.mOrigUsers;
3196                 installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
3197                         origUsers, writeSettings);
3198             }
3199         } catch (PackageManagerException e) {
3200             Slog.w(TAG, "Failed to restore system package:" + deletedPs.getPackageName() + ": "
3201                     + e.getMessage());
3202             // TODO(b/194319951): can we avoid this; throw would come from scan...
3203             throw new SystemDeleteException(e);
3204         } finally {
3205             if (disabledPs.getPkg().isStub()) {
3206                 // We've re-installed the stub; make sure it's disabled here. If package was
3207                 // originally enabled, we'll install the compressed version of the application
3208                 // and re-enable it afterward.
3209                 synchronized (mPm.mLock) {
3210                     disableStubPackage(action, deletedPs, allUserHandles);
3211                 }
3212             }
3213         }
3214     }
3215 
3216     @GuardedBy("mPm.mLock")
disableStubPackage(DeletePackageAction action, PackageSetting deletedPs, @NonNull int[] allUserHandles)3217     private void disableStubPackage(DeletePackageAction action, PackageSetting deletedPs,
3218             @NonNull int[] allUserHandles) {
3219         final PackageSetting stubPs = mPm.mSettings.getPackageLPr(
3220                 deletedPs.getPackageName());
3221         if (stubPs != null) {
3222             int userId = action.mUser == null
3223                     ? UserHandle.USER_ALL : action.mUser.getIdentifier();
3224             if (userId == UserHandle.USER_ALL) {
3225                 for (int aUserId : allUserHandles) {
3226                     stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, aUserId, "android");
3227                 }
3228             } else if (userId >= UserHandle.USER_SYSTEM) {
3229                 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, userId, "android");
3230             }
3231         }
3232     }
3233 
3234     /**
3235      * Installs a package that's already on the system partition.
3236      */
3237     @GuardedBy("mPm.mInstallLock")
installPackageFromSystemLIF(@onNull String codePathString, @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)3238     private void installPackageFromSystemLIF(@NonNull String codePathString,
3239             @NonNull int[] allUserHandles, @Nullable int[] origUserHandles,
3240             boolean writeSettings)
3241             throws PackageManagerException {
3242         final File codePath = new File(codePathString);
3243         @ParsingPackageUtils.ParseFlags int parseFlags =
3244                 mPm.getDefParseFlags()
3245                         | ParsingPackageUtils.PARSE_MUST_BE_APK
3246                         | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
3247         @PackageManagerService.ScanFlags int scanFlags = mPm.getSystemPackageScanFlags(codePath);
3248         final AndroidPackage pkg = scanSystemPackageTracedLI(
3249                 codePath, parseFlags, scanFlags, null);
3250 
3251         PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName());
3252 
3253         try {
3254             // update shared libraries for the newly re-installed system package
3255             mSharedLibraries.updateSharedLibrariesLPw(pkg, pkgSetting, null, null,
3256                     Collections.unmodifiableMap(mPm.mPackages));
3257         } catch (PackageManagerException e) {
3258             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
3259         }
3260 
3261         mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
3262 
3263         setPackageInstalledForSystemPackage(pkg, allUserHandles, origUserHandles, writeSettings);
3264     }
3265 
setPackageInstalledForSystemPackage(@onNull AndroidPackage pkg, @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)3266     private void setPackageInstalledForSystemPackage(@NonNull AndroidPackage pkg,
3267             @NonNull int[] allUserHandles, @Nullable int[] origUserHandles,
3268             boolean writeSettings) {
3269         // writer
3270         synchronized (mPm.mLock) {
3271             PackageSetting ps = mPm.mSettings.getPackageLPr(pkg.getPackageName());
3272 
3273             final boolean applyUserRestrictions = origUserHandles != null;
3274             if (applyUserRestrictions) {
3275                 boolean installedStateChanged = false;
3276                 if (DEBUG_REMOVE) {
3277                     Slog.d(TAG, "Propagating install state across reinstall");
3278                 }
3279                 for (int userId : allUserHandles) {
3280                     final boolean installed = ArrayUtils.contains(origUserHandles, userId);
3281                     if (DEBUG_REMOVE) {
3282                         Slog.d(TAG, "    user " + userId + " => " + installed);
3283                     }
3284                     if (installed != ps.getInstalled(userId)) {
3285                         installedStateChanged = true;
3286                     }
3287                     ps.setInstalled(installed, userId);
3288                     if (installed) {
3289                         ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId);
3290                     }
3291                 }
3292                 // Regardless of writeSettings we need to ensure that this restriction
3293                 // state propagation is persisted
3294                 mPm.mSettings.writeAllUsersPackageRestrictionsLPr();
3295                 if (installedStateChanged) {
3296                     mPm.mSettings.writeKernelMappingLPr(ps);
3297                 }
3298             }
3299 
3300             // The method below will take care of removing obsolete permissions and granting
3301             // install permissions.
3302             mPm.mPermissionManager.onPackageInstalled(pkg, Process.INVALID_UID,
3303                     PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
3304                     UserHandle.USER_ALL);
3305             for (final int userId : allUserHandles) {
3306                 if (applyUserRestrictions) {
3307                     mPm.mSettings.writePermissionStateForUserLPr(userId, false);
3308                 }
3309             }
3310 
3311             // can downgrade to reader here
3312             if (writeSettings) {
3313                 mPm.writeSettingsLPrTEMP();
3314             }
3315         }
3316     }
3317 
3318     @GuardedBy("mPm.mLock")
prepareSystemPackageCleanUp( WatchedArrayMap<String, PackageSetting> packageSettings, List<String> possiblyDeletedUpdatedSystemApps, ArrayMap<String, File> expectingBetter, int[] userIds)3319     public void prepareSystemPackageCleanUp(
3320             WatchedArrayMap<String, PackageSetting> packageSettings,
3321             List<String> possiblyDeletedUpdatedSystemApps,
3322             ArrayMap<String, File> expectingBetter, int[] userIds) {
3323         // Iterates PackageSettings in reversed order because the item could be removed
3324         // during the iteration.
3325         for (int index = packageSettings.size() - 1; index >= 0; index--) {
3326             final PackageSetting ps = packageSettings.valueAt(index);
3327             final String packageName = ps.getPackageName();
3328             /*
3329              * If this is not a system app, it can't be a
3330              * disable system app.
3331              */
3332             if (!ps.isSystem()) {
3333                 continue;
3334             }
3335 
3336             /*
3337              * If the package is scanned, it's not erased.
3338              */
3339             final AndroidPackage scannedPkg = mPm.mPackages.get(packageName);
3340             final PackageSetting disabledPs =
3341                     mPm.mSettings.getDisabledSystemPkgLPr(packageName);
3342             if (scannedPkg != null) {
3343                 /*
3344                  * If the system app is both scanned and in the
3345                  * disabled packages list, then it must have been
3346                  * added via OTA. Remove it from the currently
3347                  * scanned package so the previously user-installed
3348                  * application can be scanned.
3349                  */
3350                 if (disabledPs != null) {
3351                     logCriticalInfo(Log.WARN,
3352                             "Expecting better updated system app for "
3353                                     + packageName
3354                                     + "; removing system app.  Last known"
3355                                     + " codePath=" + ps.getPathString()
3356                                     + ", versionCode=" + ps.getVersionCode()
3357                                     + "; scanned versionCode="
3358                                     + scannedPkg.getLongVersionCode());
3359                     mRemovePackageHelper.removePackageLI(scannedPkg, true);
3360                     expectingBetter.put(ps.getPackageName(), ps.getPath());
3361                 }
3362 
3363                 continue;
3364             }
3365 
3366             if (disabledPs == null) {
3367                 logCriticalInfo(Log.WARN, "System package " + packageName
3368                         + " no longer exists; its data will be wiped");
3369                 mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false);
3370             } else {
3371                 // we still have a disabled system package, but, it still might have
3372                 // been removed. check the code path still exists and check there's
3373                 // still a package. the latter can happen if an OTA keeps the same
3374                 // code path, but, changes the package name.
3375                 if (disabledPs.getPath() == null || !disabledPs.getPath().exists()
3376                         || disabledPs.getPkg() == null) {
3377                     possiblyDeletedUpdatedSystemApps.add(packageName);
3378                 } else {
3379                     // We're expecting that the system app should remain disabled, but add
3380                     // it to expecting better to recover in case the data version cannot
3381                     // be scanned.
3382                     expectingBetter.put(disabledPs.getPackageName(), disabledPs.getPath());
3383                 }
3384             }
3385         }
3386     }
3387 
3388     @GuardedBy("mPm.mLock")
3389     // Remove disable package settings for updated system apps that were
3390     // removed via an OTA. If the update is no longer present, remove the
3391     // app completely. Otherwise, revoke their system privileges.
cleanupDisabledPackageSettings(List<String> possiblyDeletedUpdatedSystemApps, int[] userIds, int scanFlags)3392     public void cleanupDisabledPackageSettings(List<String> possiblyDeletedUpdatedSystemApps,
3393             int[] userIds, int scanFlags) {
3394         for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
3395             final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
3396             final AndroidPackage pkg = mPm.mPackages.get(packageName);
3397             final String msg;
3398 
3399             // remove from the disabled system list; do this first so any future
3400             // scans of this package are performed without this state
3401             mPm.mSettings.removeDisabledSystemPackageLPw(packageName);
3402 
3403             if (pkg == null) {
3404                 // should have found an update, but, we didn't; remove everything
3405                 msg = "Updated system package " + packageName
3406                         + " no longer exists; removing its data";
3407                 // Actual deletion of code and data will be handled by later
3408                 // reconciliation step
3409             } else {
3410                 // found an update; revoke system privileges
3411                 msg = "Updated system package " + packageName
3412                         + " no longer exists; rescanning package on data";
3413 
3414                 // NOTE: We don't do anything special if a stub is removed from the
3415                 // system image. But, if we were [like removing the uncompressed
3416                 // version from the /data partition], this is where it'd be done.
3417 
3418                 // remove the package from the system and re-scan it without any
3419                 // special privileges
3420                 mRemovePackageHelper.removePackageLI(pkg, true);
3421                 try {
3422                     final File codePath = new File(pkg.getPath());
3423                     scanSystemPackageTracedLI(codePath, 0, scanFlags, null);
3424                 } catch (PackageManagerException e) {
3425                     Slog.e(TAG, "Failed to parse updated, ex-system package: "
3426                             + e.getMessage());
3427                 }
3428             }
3429 
3430             // one final check. if we still have a package setting [ie. it was
3431             // previously scanned and known to the system], but, we don't have
3432             // a package [ie. there was an error scanning it from the /data
3433             // partition], completely remove the package data.
3434             final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
3435             if (ps != null && mPm.mPackages.get(packageName) == null) {
3436                 mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false);
3437             }
3438             logCriticalInfo(Log.WARN, msg);
3439         }
3440     }
3441 
3442     @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
installPackagesFromDir(File scanDir, List<File> frameworkSplits, int parseFlags, int scanFlags, PackageParser2 packageParser, ExecutorService executorService)3443     public void installPackagesFromDir(File scanDir, List<File> frameworkSplits, int parseFlags,
3444             int scanFlags, PackageParser2 packageParser,
3445             ExecutorService executorService) {
3446         final File[] files = scanDir.listFiles();
3447         if (ArrayUtils.isEmpty(files)) {
3448             Log.d(TAG, "No files in app dir " + scanDir);
3449             return;
3450         }
3451 
3452         if (DEBUG_PACKAGE_SCANNING) {
3453             Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
3454                     + " flags=0x" + Integer.toHexString(parseFlags));
3455         }
3456         ParallelPackageParser parallelPackageParser =
3457                 new ParallelPackageParser(packageParser, executorService, frameworkSplits);
3458 
3459         // Submit files for parsing in parallel
3460         int fileCount = 0;
3461         for (File file : files) {
3462             final boolean isPackage = (isApkFile(file) || file.isDirectory())
3463                     && !PackageInstallerService.isStageName(file.getName());
3464             if (!isPackage) {
3465                 // Ignore entries which are not packages
3466                 continue;
3467             }
3468             if ((scanFlags & SCAN_DROP_CACHE) != 0) {
3469                 final PackageCacher cacher = new PackageCacher(mPm.getCacheDir());
3470                 Log.w(TAG, "Dropping cache of " + file.getAbsolutePath());
3471                 cacher.cleanCachedResult(file);
3472             }
3473             parallelPackageParser.submit(file, parseFlags);
3474             fileCount++;
3475         }
3476 
3477         // Process results one by one
3478         for (; fileCount > 0; fileCount--) {
3479             ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
3480             Throwable throwable = parseResult.throwable;
3481             int errorCode = PackageManager.INSTALL_SUCCEEDED;
3482             String errorMsg = null;
3483 
3484             if (throwable == null) {
3485                 // TODO(b/194319951): move lower in the scan chain
3486                 // Static shared libraries have synthetic package names
3487                 if (parseResult.parsedPackage.isStaticSharedLibrary()) {
3488                     PackageManagerService.renameStaticSharedLibraryPackage(
3489                             parseResult.parsedPackage);
3490                 }
3491                 try {
3492                     addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
3493                             null);
3494                 } catch (PackageManagerException e) {
3495                     errorCode = e.error;
3496                     errorMsg = "Failed to scan " + parseResult.scanFile + ": " + e.getMessage();
3497                     Slog.w(TAG, errorMsg);
3498                 }
3499             } else if (throwable instanceof PackageManagerException) {
3500                 PackageManagerException e = (PackageManagerException) throwable;
3501                 errorCode = e.error;
3502                 errorMsg = "Failed to parse " + parseResult.scanFile + ": " + e.getMessage();
3503                 Slog.w(TAG, errorMsg);
3504             } else {
3505                 throw new IllegalStateException("Unexpected exception occurred while parsing "
3506                         + parseResult.scanFile, throwable);
3507             }
3508 
3509             if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) {
3510                 mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath(), errorMsg);
3511             }
3512 
3513             // Delete invalid userdata apps
3514             if ((scanFlags & SCAN_AS_SYSTEM) == 0
3515                     && errorCode != PackageManager.INSTALL_SUCCEEDED) {
3516                 logCriticalInfo(Log.WARN,
3517                         "Deleting invalid package at " + parseResult.scanFile);
3518                 mRemovePackageHelper.removeCodePathLI(parseResult.scanFile);
3519             }
3520         }
3521     }
3522 
3523     /**
3524      * Make sure all system apps that we expected to appear on
3525      * the userdata partition actually showed up. If they never
3526      * appeared, crawl back and revive the system version.
3527      */
3528     @GuardedBy("mPm.mLock")
checkExistingBetterPackages(ArrayMap<String, File> expectingBetterPackages, List<String> stubSystemApps, int systemScanFlags, int systemParseFlags)3529     public void checkExistingBetterPackages(ArrayMap<String, File> expectingBetterPackages,
3530             List<String> stubSystemApps, int systemScanFlags, int systemParseFlags) {
3531         for (int i = 0; i < expectingBetterPackages.size(); i++) {
3532             final String packageName = expectingBetterPackages.keyAt(i);
3533             if (mPm.mPackages.containsKey(packageName)) {
3534                 continue;
3535             }
3536             final File scanFile = expectingBetterPackages.valueAt(i);
3537 
3538             logCriticalInfo(Log.WARN, "Expected better " + packageName
3539                     + " but never showed up; reverting to system");
3540 
3541             final Pair<Integer, Integer> rescanAndReparseFlags =
3542                     mPm.getSystemPackageRescanFlagsAndReparseFlags(scanFile,
3543                             systemScanFlags, systemParseFlags);
3544             @PackageManagerService.ScanFlags int rescanFlags = rescanAndReparseFlags.first;
3545             @ParsingPackageUtils.ParseFlags int reparseFlags = rescanAndReparseFlags.second;
3546 
3547             if (rescanFlags == 0) {
3548                 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
3549                 continue;
3550             }
3551             mPm.mSettings.enableSystemPackageLPw(packageName);
3552 
3553             try {
3554                 final AndroidPackage newPkg = scanSystemPackageTracedLI(
3555                         scanFile, reparseFlags, rescanFlags, null);
3556                 // We rescanned a stub, add it to the list of stubbed system packages
3557                 if (newPkg.isStub()) {
3558                     stubSystemApps.add(packageName);
3559                 }
3560             } catch (PackageManagerException e) {
3561                 Slog.e(TAG, "Failed to parse original system package: "
3562                         + e.getMessage());
3563             }
3564         }
3565     }
3566 
3567     /**
3568      *  Traces a package scan.
3569      *  @see #scanSystemPackageLI(File, int, int, UserHandle)
3570      */
3571     @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
scanSystemPackageTracedLI(File scanFile, final int parseFlags, int scanFlags, UserHandle user)3572     public AndroidPackage scanSystemPackageTracedLI(File scanFile, final int parseFlags,
3573             int scanFlags, UserHandle user) throws PackageManagerException {
3574         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
3575         try {
3576             return scanSystemPackageLI(scanFile, parseFlags, scanFlags, user);
3577         } finally {
3578             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3579         }
3580     }
3581 
3582     /**
3583      *  Scans a package and returns the newly parsed package.
3584      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
3585      */
3586     @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags, UserHandle user)3587     private AndroidPackage scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags,
3588             UserHandle user) throws PackageManagerException {
3589         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
3590 
3591         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
3592         final ParsedPackage parsedPackage;
3593         try (PackageParser2 pp = mPm.mInjector.getScanningPackageParser()) {
3594             parsedPackage = pp.parsePackage(scanFile, parseFlags, false);
3595         } finally {
3596             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3597         }
3598 
3599         // Static shared libraries have synthetic package names
3600         if (parsedPackage.isStaticSharedLibrary()) {
3601             PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage);
3602         }
3603 
3604         return addForInitLI(parsedPackage, parseFlags, scanFlags, user);
3605     }
3606 
3607     /**
3608      * Adds a new package to the internal data structures during platform initialization.
3609      * <p>After adding, the package is known to the system and available for querying.
3610      * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
3611      * etc...], additional checks are performed. Basic verification [such as ensuring
3612      * matching signatures, checking version codes, etc...] occurs if the package is
3613      * identical to a previously known package. If the package fails a signature check,
3614      * the version installed on /data will be removed. If the version of the new package
3615      * is less than or equal than the version on /data, it will be ignored.
3616      * <p>Regardless of the package location, the results are applied to the internal
3617      * structures and the package is made available to the rest of the system.
3618      * <p>NOTE: The return value should be removed. It's the passed in package object.
3619      */
3620     @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
addForInitLI(ParsedPackage parsedPackage, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, @Nullable UserHandle user)3621     private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
3622             @ParsingPackageUtils.ParseFlags int parseFlags,
3623             @PackageManagerService.ScanFlags int scanFlags,
3624             @Nullable UserHandle user) throws PackageManagerException {
3625 
3626         final Pair<ScanResult, Boolean> scanResultPair = scanSystemPackageLI(
3627                 parsedPackage, parseFlags, scanFlags, user);
3628         final ScanResult scanResult = scanResultPair.first;
3629         boolean shouldHideSystemApp = scanResultPair.second;
3630         if (scanResult.mSuccess) {
3631             synchronized (mPm.mLock) {
3632                 boolean appIdCreated = false;
3633                 try {
3634                     final String pkgName = scanResult.mPkgSetting.getPackageName();
3635                     final ReconcileRequest reconcileRequest = new ReconcileRequest(
3636                             Collections.singletonMap(pkgName, scanResult),
3637                             mPm.mPackages,
3638                             Collections.singletonMap(pkgName,
3639                                     mPm.getSettingsVersionForPackage(parsedPackage)));
3640                     final Map<String, ReconciledPackage> reconcileResult =
3641                             ReconcilePackageUtils.reconcilePackages(reconcileRequest,
3642                                     mSharedLibraries, mPm.mSettings.getKeySetManagerService(),
3643                                     mPm.mSettings);
3644                     appIdCreated = optimisticallyRegisterAppId(scanResult);
3645                     commitReconciledScanResultLocked(reconcileResult.get(pkgName),
3646                             mPm.mUserManager.getUserIds());
3647                 } catch (PackageManagerException e) {
3648                     if (appIdCreated) {
3649                         cleanUpAppIdCreation(scanResult);
3650                     }
3651                     throw e;
3652                 }
3653             }
3654         }
3655 
3656         if (shouldHideSystemApp) {
3657             synchronized (mPm.mLock) {
3658                 mPm.mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true);
3659             }
3660         }
3661         if (mIncrementalManager != null && isIncrementalPath(parsedPackage.getPath())) {
3662             if (scanResult.mPkgSetting != null && scanResult.mPkgSetting.isLoading()) {
3663                 // Continue monitoring loading progress of active incremental packages
3664                 mIncrementalManager.registerLoadingProgressCallback(parsedPackage.getPath(),
3665                         new IncrementalProgressListener(parsedPackage.getPackageName(), mPm));
3666             }
3667         }
3668         return scanResult.mPkgSetting.getPkg();
3669     }
3670 
3671     /**
3672      * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering
3673      * the app ID required for reconcile.
3674      * @return {@code true} if a new app ID was registered and will need to be cleaned up on
3675      *         failure.
3676      */
optimisticallyRegisterAppId(@onNull ScanResult result)3677     private boolean optimisticallyRegisterAppId(@NonNull ScanResult result)
3678             throws PackageManagerException {
3679         if (!result.mExistingSettingCopied || result.needsNewAppId()) {
3680             synchronized (mPm.mLock) {
3681                 // THROWS: when we can't allocate a user id. add call to check if there's
3682                 // enough space to ensure we won't throw; otherwise, don't modify state
3683                 return mPm.mSettings.registerAppIdLPw(result.mPkgSetting, result.needsNewAppId());
3684             }
3685         }
3686         return false;
3687     }
3688 
3689     /**
3690      * Reverts any app ID creation that were made by
3691      * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
3692      * referenced method returned true.
3693      */
cleanUpAppIdCreation(@onNull ScanResult result)3694     private void cleanUpAppIdCreation(@NonNull ScanResult result) {
3695         // iff we've acquired an app ID for a new package setting, remove it so that it can be
3696         // acquired by another request.
3697         if (result.mPkgSetting.getAppId() > 0) {
3698             mPm.mSettings.removeAppIdLPw(result.mPkgSetting.getAppId());
3699         }
3700     }
3701 
3702     @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
scanPackageTracedLI(ParsedPackage parsedPackage, final @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user, String cpuAbiOverride)3703     private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
3704             final @ParsingPackageUtils.ParseFlags int parseFlags,
3705             @PackageManagerService.ScanFlags int scanFlags, long currentTime,
3706             @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
3707         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
3708         try {
3709             return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user,
3710                     cpuAbiOverride);
3711         } finally {
3712             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3713         }
3714     }
3715 
prepareInitialScanRequest(@onNull ParsedPackage parsedPackage, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, @Nullable UserHandle user, String cpuAbiOverride)3716     private ScanRequest prepareInitialScanRequest(@NonNull ParsedPackage parsedPackage,
3717             @ParsingPackageUtils.ParseFlags int parseFlags,
3718             @PackageManagerService.ScanFlags int scanFlags,
3719             @Nullable UserHandle user, String cpuAbiOverride)
3720             throws PackageManagerException {
3721         final AndroidPackage platformPackage;
3722         final String realPkgName;
3723         final PackageSetting disabledPkgSetting;
3724         final PackageSetting installedPkgSetting;
3725         final PackageSetting originalPkgSetting;
3726         final SharedUserSetting sharedUserSetting;
3727         SharedUserSetting oldSharedUserSetting = null;
3728 
3729         synchronized (mPm.mLock) {
3730             platformPackage = mPm.getPlatformPackage();
3731             final String renamedPkgName = mPm.mSettings.getRenamedPackageLPr(
3732                     AndroidPackageUtils.getRealPackageOrNull(parsedPackage));
3733             realPkgName = ScanPackageUtils.getRealPackageName(parsedPackage, renamedPkgName);
3734             if (realPkgName != null) {
3735                 ScanPackageUtils.ensurePackageRenamed(parsedPackage, renamedPkgName);
3736             }
3737             originalPkgSetting = getOriginalPackageLocked(parsedPackage, renamedPkgName);
3738             installedPkgSetting = mPm.mSettings.getPackageLPr(parsedPackage.getPackageName());
3739             if (mPm.mTransferredPackages.contains(parsedPackage.getPackageName())) {
3740                 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
3741                         + " was transferred to another, but its .apk remains");
3742             }
3743             disabledPkgSetting = mPm.mSettings.getDisabledSystemPkgLPr(
3744                     parsedPackage.getPackageName());
3745 
3746             boolean ignoreSharedUserId = false;
3747             if (installedPkgSetting == null || !installedPkgSetting.hasSharedUser()) {
3748                 // Directly ignore sharedUserSetting for new installs, or if the app has
3749                 // already left shared UID
3750                 ignoreSharedUserId = parsedPackage.isLeavingSharedUid();
3751             }
3752 
3753             if (!ignoreSharedUserId && parsedPackage.getSharedUserId() != null) {
3754                 sharedUserSetting = mPm.mSettings.getSharedUserLPw(
3755                         parsedPackage.getSharedUserId(),
3756                         0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
3757             } else {
3758                 sharedUserSetting = null;
3759             }
3760             if (DEBUG_PACKAGE_SCANNING
3761                     && (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0
3762                     && sharedUserSetting != null) {
3763                 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
3764                         + " (uid=" + sharedUserSetting.mAppId + "):"
3765                         + " packages=" + sharedUserSetting.getPackageStates());
3766             }
3767             if (installedPkgSetting != null) {
3768                 oldSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(installedPkgSetting);
3769             }
3770         }
3771 
3772         final boolean isPlatformPackage = platformPackage != null
3773                 && platformPackage.getPackageName().equals(parsedPackage.getPackageName());
3774 
3775         return new ScanRequest(parsedPackage, oldSharedUserSetting,
3776                 installedPkgSetting == null ? null : installedPkgSetting.getPkg() /* oldPkg */,
3777                 installedPkgSetting /* packageSetting */,
3778                 sharedUserSetting,
3779                 disabledPkgSetting /* disabledPackageSetting */,
3780                 originalPkgSetting  /* originalPkgSetting */,
3781                 realPkgName, parseFlags, scanFlags, isPlatformPackage, user, cpuAbiOverride);
3782     }
3783 
3784     @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
scanPackageNewLI(@onNull ParsedPackage parsedPackage, final @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user, String cpuAbiOverride)3785     private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
3786             final @ParsingPackageUtils.ParseFlags int parseFlags,
3787             @PackageManagerService.ScanFlags int scanFlags, long currentTime,
3788             @Nullable UserHandle user, String cpuAbiOverride)
3789             throws PackageManagerException {
3790         final ScanRequest initialScanRequest = prepareInitialScanRequest(parsedPackage, parseFlags,
3791                 scanFlags, user, cpuAbiOverride);
3792         final PackageSetting installedPkgSetting = initialScanRequest.mPkgSetting;
3793         final PackageSetting disabledPkgSetting = initialScanRequest.mDisabledPkgSetting;
3794 
3795         boolean isUpdatedSystemApp;
3796         if (installedPkgSetting != null) {
3797             isUpdatedSystemApp = installedPkgSetting.getPkgState().isUpdatedSystemApp();
3798         } else {
3799             isUpdatedSystemApp = disabledPkgSetting != null;
3800         }
3801 
3802         final int newScanFlags = adjustScanFlags(scanFlags, installedPkgSetting, disabledPkgSetting,
3803                 user, parsedPackage);
3804         ScanPackageUtils.applyPolicy(parsedPackage, newScanFlags,
3805                 mPm.getPlatformPackage(), isUpdatedSystemApp);
3806 
3807         synchronized (mPm.mLock) {
3808             assertPackageIsValid(parsedPackage, parseFlags, newScanFlags);
3809             final ScanRequest request = new ScanRequest(parsedPackage,
3810                     initialScanRequest.mOldSharedUserSetting,
3811                     initialScanRequest.mOldPkg, installedPkgSetting,
3812                     initialScanRequest.mSharedUserSetting, disabledPkgSetting,
3813                     initialScanRequest.mOriginalPkgSetting, initialScanRequest.mRealPkgName,
3814                     parseFlags, scanFlags, initialScanRequest.mIsPlatformPackage, user,
3815                     cpuAbiOverride);
3816             return ScanPackageUtils.scanPackageOnlyLI(request, mPm.mInjector, mPm.mFactoryTest,
3817                     currentTime);
3818         }
3819     }
3820 
scanSystemPackageLI(ParsedPackage parsedPackage, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, @Nullable UserHandle user)3821     private Pair<ScanResult, Boolean> scanSystemPackageLI(ParsedPackage parsedPackage,
3822             @ParsingPackageUtils.ParseFlags int parseFlags,
3823             @PackageManagerService.ScanFlags int scanFlags,
3824             @Nullable UserHandle user) throws PackageManagerException {
3825         final boolean scanSystemPartition =
3826                 (parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0;
3827         final ScanRequest initialScanRequest = prepareInitialScanRequest(parsedPackage, parseFlags,
3828                 scanFlags, user, null);
3829         final PackageSetting installedPkgSetting = initialScanRequest.mPkgSetting;
3830         final PackageSetting originalPkgSetting = initialScanRequest.mOriginalPkgSetting;
3831         final PackageSetting pkgSetting =
3832                 originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
3833         final boolean pkgAlreadyExists = pkgSetting != null;
3834         final String disabledPkgName = pkgAlreadyExists
3835                 ? pkgSetting.getPackageName() : parsedPackage.getPackageName();
3836         final boolean isSystemPkgUpdated;
3837         final boolean isUpgrade;
3838         synchronized (mPm.mLock) {
3839             isUpgrade = mPm.isDeviceUpgrading();
3840             if (scanSystemPartition && !pkgAlreadyExists
3841                     && mPm.mSettings.getDisabledSystemPkgLPr(disabledPkgName) != null) {
3842                 // The updated-package data for /system apk remains inconsistently
3843                 // after the package data for /data apk is lost accidentally.
3844                 // To recover it, enable /system apk and install it as non-updated system app.
3845                 Slog.w(TAG, "Inconsistent package setting of updated system app for "
3846                         + disabledPkgName + ". To recover it, enable the system app "
3847                         + "and install it as non-updated system app.");
3848                 mPm.mSettings.removeDisabledSystemPackageLPw(disabledPkgName);
3849             }
3850             final PackageSetting disabledPkgSetting =
3851                     mPm.mSettings.getDisabledSystemPkgLPr(disabledPkgName);
3852             isSystemPkgUpdated = disabledPkgSetting != null;
3853 
3854             if (DEBUG_INSTALL && isSystemPkgUpdated) {
3855                 Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
3856             }
3857 
3858             if (scanSystemPartition && isSystemPkgUpdated) {
3859                 // we're updating the disabled package, so, scan it as the package setting
3860                 final ScanRequest request = new ScanRequest(parsedPackage,
3861                         mPm.mSettings.getSharedUserSettingLPr(disabledPkgSetting),
3862                         null, disabledPkgSetting /* pkgSetting */,
3863                         initialScanRequest.mSharedUserSetting,
3864                         null /* disabledPkgSetting */, null /* originalPkgSetting */,
3865                         null, parseFlags, scanFlags,
3866                         initialScanRequest.mIsPlatformPackage, user, null);
3867                 ScanPackageUtils.applyPolicy(parsedPackage, scanFlags,
3868                         mPm.getPlatformPackage(), true);
3869                 final ScanResult scanResult =
3870                         ScanPackageUtils.scanPackageOnlyLI(request, mPm.mInjector,
3871                                 mPm.mFactoryTest, -1L);
3872                 if (scanResult.mExistingSettingCopied
3873                         && scanResult.mRequest.mPkgSetting != null) {
3874                     scanResult.mRequest.mPkgSetting.updateFrom(scanResult.mPkgSetting);
3875                 }
3876             }
3877         } // End of mLock
3878 
3879         final boolean newPkgChangedPaths = pkgAlreadyExists
3880                 && !pkgSetting.getPathString().equals(parsedPackage.getPath());
3881         final boolean newPkgVersionGreater = pkgAlreadyExists
3882                 && parsedPackage.getLongVersionCode() > pkgSetting.getVersionCode();
3883         final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
3884                 && newPkgChangedPaths && newPkgVersionGreater;
3885         if (isSystemPkgBetter) {
3886             // The version of the application on /system is greater than the version on
3887             // /data. Switch back to the application on /system.
3888             // It's safe to assume the application on /system will correctly scan. If not,
3889             // there won't be a working copy of the application.
3890             synchronized (mPm.mLock) {
3891                 // just remove the loaded entries from package lists
3892                 mPm.mPackages.remove(pkgSetting.getPackageName());
3893             }
3894 
3895             logCriticalInfo(Log.WARN,
3896                     "System package updated;"
3897                             + " name: " + pkgSetting.getPackageName()
3898                             + "; " + pkgSetting.getVersionCode() + " --> "
3899                             + parsedPackage.getLongVersionCode()
3900                             + "; " + pkgSetting.getPathString()
3901                             + " --> " + parsedPackage.getPath());
3902 
3903             final InstallArgs args = new FileInstallArgs(
3904                     pkgSetting.getPathString(), getAppDexInstructionSets(
3905                     pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()), mPm);
3906             args.cleanUpResourcesLI();
3907             synchronized (mPm.mLock) {
3908                 mPm.mSettings.enableSystemPackageLPw(pkgSetting.getPackageName());
3909             }
3910         }
3911 
3912         // The version of the application on the /system partition is less than or
3913         // equal to the version on the /data partition. Throw an exception and use
3914         // the application already installed on the /data partition.
3915         if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
3916             // In the case of a skipped package, commitReconciledScanResultLocked is not called to
3917             // add the object to the "live" data structures, so this is the final mutation step
3918             // for the package. Which means it needs to be finalized here to cache derived fields.
3919             // This is relevant for cases where the disabled system package is used for flags or
3920             // other metadata.
3921             parsedPackage.hideAsFinal();
3922             throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName()
3923                     + " at " + parsedPackage.getPath() + " ignored: updated version "
3924                     + (pkgAlreadyExists ? String.valueOf(pkgSetting.getVersionCode()) : "unknown")
3925                     + " better than this " + parsedPackage.getLongVersionCode());
3926         }
3927 
3928         // Verify certificates against what was last scanned. Force re-collecting certificate in two
3929         // special cases:
3930         // 1) when scanning system, force re-collect only if system is upgrading.
3931         // 2) when scanning /data, force re-collect only if the app is privileged (updated from
3932         // preinstall, or treated as privileged, e.g. due to shared user ID).
3933         final boolean forceCollect = scanSystemPartition ? isUpgrade
3934                 : PackageManagerServiceUtils.isApkVerificationForced(pkgSetting);
3935         if (DEBUG_VERIFY && forceCollect) {
3936             Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName());
3937         }
3938 
3939         // Full APK verification can be skipped during certificate collection, only if the file is
3940         // in verified partition, or can be verified on access (when apk verity is enabled). In both
3941         // cases, only data in Signing Block is verified instead of the whole file.
3942         final boolean skipVerify = scanSystemPartition
3943                 || (forceCollect && canSkipForcedPackageVerification(parsedPackage));
3944         ScanPackageUtils.collectCertificatesLI(pkgSetting, parsedPackage,
3945                 mPm.getSettingsVersionForPackage(parsedPackage), forceCollect, skipVerify,
3946                 mPm.isPreNMR1Upgrade());
3947 
3948         // Reset profile if the application version is changed
3949         maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage);
3950 
3951         /*
3952          * A new system app appeared, but we already had a non-system one of the
3953          * same name installed earlier.
3954          */
3955         boolean shouldHideSystemApp = false;
3956         // A new application appeared on /system, but, we already have a copy of
3957         // the application installed on /data.
3958         if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
3959                 && !pkgSetting.isSystem()) {
3960 
3961             if (!parsedPackage.getSigningDetails()
3962                     .checkCapability(pkgSetting.getSigningDetails(),
3963                             SigningDetails.CertCapabilities.INSTALLED_DATA)
3964                     && !pkgSetting.getSigningDetails().checkCapability(
3965                     parsedPackage.getSigningDetails(),
3966                     SigningDetails.CertCapabilities.ROLLBACK)) {
3967                 logCriticalInfo(Log.WARN,
3968                         "System package signature mismatch;"
3969                                 + " name: " + pkgSetting.getPackageName());
3970                 try (@SuppressWarnings("unused") PackageFreezer freezer = mPm.freezePackage(
3971                         parsedPackage.getPackageName(),
3972                         "scanPackageInternalLI")) {
3973                     DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm);
3974                     deletePackageHelper.deletePackageLIF(parsedPackage.getPackageName(), null, true,
3975                             mPm.mUserManager.getUserIds(), 0, null, false);
3976                 }
3977             } else if (newPkgVersionGreater) {
3978                 // The application on /system is newer than the application on /data.
3979                 // Simply remove the application on /data [keeping application data]
3980                 // and replace it with the version on /system.
3981                 logCriticalInfo(Log.WARN,
3982                         "System package enabled;"
3983                                 + " name: " + pkgSetting.getPackageName()
3984                                 + "; " + pkgSetting.getVersionCode() + " --> "
3985                                 + parsedPackage.getLongVersionCode()
3986                                 + "; " + pkgSetting.getPathString() + " --> "
3987                                 + parsedPackage.getPath());
3988                 InstallArgs args = new FileInstallArgs(
3989                         pkgSetting.getPathString(), getAppDexInstructionSets(
3990                         pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()),
3991                         mPm);
3992                 synchronized (mPm.mInstallLock) {
3993                     args.cleanUpResourcesLI();
3994                 }
3995             } else {
3996                 // The application on /system is older than the application on /data. Hide
3997                 // the application on /system and the version on /data will be scanned later
3998                 // and re-added like an update.
3999                 shouldHideSystemApp = true;
4000                 logCriticalInfo(Log.INFO,
4001                         "System package disabled;"
4002                                 + " name: " + pkgSetting.getPackageName()
4003                                 + "; old: " + pkgSetting.getPathString() + " @ "
4004                                 + pkgSetting.getVersionCode()
4005                                 + "; new: " + parsedPackage.getPath() + " @ "
4006                                 + parsedPackage.getPath());
4007             }
4008         }
4009 
4010         final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags,
4011                 scanFlags | SCAN_UPDATE_SIGNATURE, 0 /* currentTime */, user, null);
4012         return new Pair<>(scanResult, shouldHideSystemApp);
4013     }
4014 
4015     /**
4016      * Returns if forced apk verification can be skipped for the whole package, including splits.
4017      */
canSkipForcedPackageVerification(AndroidPackage pkg)4018     private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
4019         final String packageName = pkg.getPackageName();
4020         if (!VerityUtils.hasFsverity(pkg.getBaseApkPath())) {
4021             return false;
4022         }
4023         // TODO: Allow base and splits to be verified individually.
4024         String[] splitCodePaths = pkg.getSplitCodePaths();
4025         if (!ArrayUtils.isEmpty(splitCodePaths)) {
4026             for (int i = 0; i < splitCodePaths.length; i++) {
4027                 if (!VerityUtils.hasFsverity(splitCodePaths[i])) {
4028                     return false;
4029                 }
4030             }
4031         }
4032         return true;
4033     }
4034 
4035     /**
4036      * Clear the package profile if this was an upgrade and the package
4037      * version was updated.
4038      */
maybeClearProfilesForUpgradesLI( @ullable PackageSetting originalPkgSetting, @NonNull AndroidPackage pkg)4039     private void maybeClearProfilesForUpgradesLI(
4040             @Nullable PackageSetting originalPkgSetting,
4041             @NonNull AndroidPackage pkg) {
4042         if (originalPkgSetting == null || !mPm.isDeviceUpgrading()) {
4043             return;
4044         }
4045         if (originalPkgSetting.getVersionCode() == pkg.getLongVersionCode()) {
4046             return;
4047         }
4048 
4049         mAppDataHelper.clearAppProfilesLIF(pkg);
4050         if (DEBUG_INSTALL) {
4051             Slog.d(TAG, originalPkgSetting.getPackageName()
4052                     + " clear profile due to version change "
4053                     + originalPkgSetting.getVersionCode() + " != "
4054                     + pkg.getLongVersionCode());
4055         }
4056     }
4057 
4058     /**
4059      * Returns the original package setting.
4060      * <p>A package can migrate its name during an update. In this scenario, a package
4061      * designates a set of names that it considers as one of its original names.
4062      * <p>An original package must be signed identically and it must have the same
4063      * shared user [if any].
4064      */
4065     @GuardedBy("mPm.mLock")
4066     @Nullable
getOriginalPackageLocked(@onNull AndroidPackage pkg, @Nullable String renamedPkgName)4067     private PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg,
4068             @Nullable String renamedPkgName) {
4069         if (ScanPackageUtils.isPackageRenamed(pkg, renamedPkgName)) {
4070             return null;
4071         }
4072         for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) {
4073             final PackageSetting originalPs =
4074                     mPm.mSettings.getPackageLPr(pkg.getOriginalPackages().get(i));
4075             if (originalPs != null) {
4076                 // the package is already installed under its original name...
4077                 // but, should we use it?
4078                 if (!verifyPackageUpdateLPr(originalPs, pkg)) {
4079                     // the new package is incompatible with the original
4080                     continue;
4081                 } else if (mPm.mSettings.getSharedUserSettingLPr(originalPs) != null) {
4082                     final String sharedUserSettingsName =
4083                             mPm.mSettings.getSharedUserSettingLPr(originalPs).name;
4084                     if (!sharedUserSettingsName.equals(pkg.getSharedUserId())) {
4085                         // the shared user id is incompatible with the original
4086                         Slog.w(TAG, "Unable to migrate data from " + originalPs.getPackageName()
4087                                 + " to " + pkg.getPackageName() + ": old shared user settings name "
4088                                 + sharedUserSettingsName
4089                                 + " differs from " + pkg.getSharedUserId());
4090                         continue;
4091                     }
4092                     // TODO: Add case when shared user id is added [b/28144775]
4093                 } else {
4094                     if (DEBUG_UPGRADE) {
4095                         Log.v(TAG, "Renaming new package "
4096                                 + pkg.getPackageName() + " to old name "
4097                                 + originalPs.getPackageName());
4098                     }
4099                 }
4100                 return originalPs;
4101             }
4102         }
4103         return null;
4104     }
4105 
4106     @GuardedBy("mPm.mLock")
verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg)4107     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) {
4108         if ((oldPkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) == 0) {
4109             Slog.w(TAG, "Unable to update from " + oldPkg.getPackageName()
4110                     + " to " + newPkg.getPackageName()
4111                     + ": old package not in system partition");
4112             return false;
4113         } else if (mPm.mPackages.get(oldPkg.getPackageName()) != null) {
4114             Slog.w(TAG, "Unable to update from " + oldPkg.getPackageName()
4115                     + " to " + newPkg.getPackageName()
4116                     + ": old package still exists");
4117             return false;
4118         }
4119         return true;
4120     }
4121 
4122     /**
4123      * Asserts the parsed package is valid according to the given policy. If the
4124      * package is invalid, for whatever reason, throws {@link PackageManagerException}.
4125      * <p>
4126      * Implementation detail: This method must NOT have any side effects. It would
4127      * ideally be static, but, it requires locks to read system state.
4128      *
4129      * @throws PackageManagerException If the package fails any of the validation checks
4130      */
assertPackageIsValid(AndroidPackage pkg, final @ParsingPackageUtils.ParseFlags int parseFlags, final @PackageManagerService.ScanFlags int scanFlags)4131     private void assertPackageIsValid(AndroidPackage pkg,
4132             final @ParsingPackageUtils.ParseFlags int parseFlags,
4133             final @PackageManagerService.ScanFlags int scanFlags)
4134             throws PackageManagerException {
4135         if ((parseFlags & ParsingPackageUtils.PARSE_ENFORCE_CODE) != 0) {
4136             ScanPackageUtils.assertCodePolicy(pkg);
4137         }
4138 
4139         if (pkg.getPath() == null) {
4140             // Bail out. The resource and code paths haven't been set.
4141             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
4142                     "Code and resource paths haven't been set correctly");
4143         }
4144 
4145         // Check that there is an APEX package with the same name only during install/first boot
4146         // after OTA.
4147         final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0;
4148         final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
4149         if ((isUserInstall || isFirstBootOrUpgrade)
4150                 && mApexManager.isApexPackage(pkg.getPackageName())) {
4151             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
4152                     pkg.getPackageName()
4153                             + " is an APEX package and can't be installed as an APK.");
4154         }
4155 
4156         // Make sure we're not adding any bogus keyset info
4157         final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
4158         ksms.assertScannedPackageValid(pkg);
4159 
4160         synchronized (mPm.mLock) {
4161             // The special "android" package can only be defined once
4162             if (pkg.getPackageName().equals("android")) {
4163                 if (mPm.getCoreAndroidApplication() != null) {
4164                     Slog.w(TAG, "*************************************************");
4165                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
4166                     Slog.w(TAG, " codePath=" + pkg.getPath());
4167                     Slog.w(TAG, "*************************************************");
4168                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
4169                             "Core android package being redefined.  Skipping.");
4170                 }
4171             }
4172 
4173             // A package name must be unique; don't allow duplicates
4174             if ((scanFlags & SCAN_NEW_INSTALL) == 0
4175                     && mPm.mPackages.containsKey(pkg.getPackageName())) {
4176                 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
4177                         "Application package " + pkg.getPackageName()
4178                                 + " already installed.  Skipping duplicate.");
4179             }
4180 
4181             if (pkg.isStaticSharedLibrary()) {
4182                 // Static libs have a synthetic package name containing the version
4183                 // but we still want the base name to be unique.
4184                 if ((scanFlags & SCAN_NEW_INSTALL) == 0
4185                         && mPm.mPackages.containsKey(pkg.getManifestPackageName())) {
4186                     throw new PackageManagerException(
4187                             "Duplicate static shared lib provider package");
4188                 }
4189                 ScanPackageUtils.assertStaticSharedLibraryIsValid(pkg, scanFlags);
4190                 assertStaticSharedLibraryVersionCodeIsValid(pkg);
4191             }
4192 
4193             // If we're only installing presumed-existing packages, require that the
4194             // scanned APK is both already known and at the path previously established
4195             // for it.  Previously unknown packages we pick up normally, but if we have an
4196             // a priori expectation about this package's install presence, enforce it.
4197             // With a singular exception for new system packages. When an OTA contains
4198             // a new system package, we allow the codepath to change from a system location
4199             // to the user-installed location. If we don't allow this change, any newer,
4200             // user-installed version of the application will be ignored.
4201             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
4202                 if (mPm.isExpectingBetter(pkg.getPackageName())) {
4203                     Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package "
4204                             + pkg.getPackageName());
4205                 } else {
4206                     PackageSetting known = mPm.mSettings.getPackageLPr(pkg.getPackageName());
4207                     if (known != null) {
4208                         if (DEBUG_PACKAGE_SCANNING) {
4209                             Log.d(TAG, "Examining " + pkg.getPath()
4210                                     + " and requiring known path " + known.getPathString());
4211                         }
4212                         if (!pkg.getPath().equals(known.getPathString())) {
4213                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
4214                                     "Application package " + pkg.getPackageName()
4215                                             + " found at " + pkg.getPath()
4216                                             + " but expected at " + known.getPathString()
4217                                             + "; ignoring.");
4218                         }
4219                     } else {
4220                         throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
4221                                 "Application package " + pkg.getPackageName()
4222                                         + " not found; ignoring.");
4223                     }
4224                 }
4225             }
4226 
4227             // Verify that this new package doesn't have any content providers
4228             // that conflict with existing packages.  Only do this if the
4229             // package isn't already installed, since we don't want to break
4230             // things that are installed.
4231             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
4232                 mPm.mComponentResolver.assertProvidersNotDefined(pkg);
4233             }
4234 
4235             // If this package has defined explicit processes, then ensure that these are
4236             // the only processes used by its components.
4237             ScanPackageUtils.assertProcessesAreValid(pkg);
4238 
4239             // Verify that packages sharing a user with a privileged app are marked as privileged.
4240             assertPackageWithSharedUserIdIsPrivileged(pkg);
4241 
4242             // Apply policies specific for runtime resource overlays (RROs).
4243             if (pkg.getOverlayTarget() != null) {
4244                 assertOverlayIsValid(pkg, parseFlags, scanFlags);
4245             }
4246 
4247             // Ensure the package is signed with at least the minimum signature scheme version
4248             // required for its target SDK.
4249             ScanPackageUtils.assertMinSignatureSchemeIsValid(pkg, parseFlags);
4250         }
4251     }
4252 
assertStaticSharedLibraryVersionCodeIsValid(AndroidPackage pkg)4253     private void assertStaticSharedLibraryVersionCodeIsValid(AndroidPackage pkg)
4254             throws PackageManagerException {
4255         // The version codes must be ordered as lib versions
4256         long minVersionCode = Long.MIN_VALUE;
4257         long maxVersionCode = Long.MAX_VALUE;
4258 
4259         WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
4260                 mSharedLibraries.getSharedLibraryInfos(pkg.getStaticSharedLibName());
4261         if (versionedLib != null) {
4262             final int versionCount = versionedLib.size();
4263             for (int i = 0; i < versionCount; i++) {
4264                 SharedLibraryInfo libInfo = versionedLib.valueAt(i);
4265                 final long libVersionCode = libInfo.getDeclaringPackage()
4266                         .getLongVersionCode();
4267                 if (libInfo.getLongVersion() < pkg.getStaticSharedLibVersion()) {
4268                     minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
4269                 } else if (libInfo.getLongVersion()
4270                         > pkg.getStaticSharedLibVersion()) {
4271                     maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
4272                 } else {
4273                     minVersionCode = maxVersionCode = libVersionCode;
4274                     break;
4275                 }
4276             }
4277         }
4278         if (pkg.getLongVersionCode() < minVersionCode
4279                 || pkg.getLongVersionCode() > maxVersionCode) {
4280             throw new PackageManagerException("Static shared"
4281                     + " lib version codes must be ordered as lib versions");
4282         }
4283     }
4284 
assertOverlayIsValid(AndroidPackage pkg, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags)4285     private void assertOverlayIsValid(AndroidPackage pkg,
4286             @ParsingPackageUtils.ParseFlags int parseFlags,
4287             @PackageManagerService.ScanFlags int scanFlags) throws PackageManagerException {
4288         // System overlays have some restrictions on their use of the 'static' state.
4289         if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
4290             // We are scanning a system overlay. This can be the first scan of the
4291             // system/vendor/oem partition, or an update to the system overlay.
4292             if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) {
4293                 // This must be an update to a system overlay. Immutable overlays cannot be
4294                 // upgraded.
4295                 if (!mPm.isOverlayMutable(pkg.getPackageName())) {
4296                     throw new PackageManagerException("Overlay "
4297                             + pkg.getPackageName()
4298                             + " is static and cannot be upgraded.");
4299                 }
4300             } else {
4301                 if ((scanFlags & SCAN_AS_VENDOR) != 0) {
4302                     if (pkg.getTargetSdkVersion() < ScanPackageUtils.getVendorPartitionVersion()) {
4303                         Slog.w(TAG, "System overlay " + pkg.getPackageName()
4304                                 + " targets an SDK below the required SDK level of vendor"
4305                                 + " overlays ("
4306                                 + ScanPackageUtils.getVendorPartitionVersion()
4307                                 + ")."
4308                                 + " This will become an install error in a future release");
4309                     }
4310                 } else if (pkg.getTargetSdkVersion() < Build.VERSION.SDK_INT) {
4311                     Slog.w(TAG, "System overlay " + pkg.getPackageName()
4312                             + " targets an SDK below the required SDK level of system"
4313                             + " overlays (" + Build.VERSION.SDK_INT + ")."
4314                             + " This will become an install error in a future release");
4315                 }
4316             }
4317         } else {
4318             // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
4319             // signed with the platform certificate. Check this in increasing order of
4320             // computational cost.
4321             if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
4322                 final PackageSetting platformPkgSetting =
4323                         mPm.mSettings.getPackageLPr("android");
4324                 if (!comparePackageSignatures(platformPkgSetting,
4325                         pkg.getSigningDetails().getSignatures())) {
4326                     throw new PackageManagerException("Overlay "
4327                             + pkg.getPackageName()
4328                             + " must target Q or later, "
4329                             + "or be signed with the platform certificate");
4330                 }
4331             }
4332 
4333             // A non-preloaded overlay package, without <overlay android:targetName>, will
4334             // only be used if it is signed with the same certificate as its target OR if
4335             // it is signed with the same certificate as a reference package declared
4336             // in 'overlay-config-signature' tag of SystemConfig.
4337             // If the target is already installed or 'overlay-config-signature' tag in
4338             // SystemConfig is set, check this here to augment the last line of defense
4339             // which is OMS.
4340             if (pkg.getOverlayTargetOverlayableName() == null) {
4341                 final PackageSetting targetPkgSetting =
4342                         mPm.mSettings.getPackageLPr(pkg.getOverlayTarget());
4343                 if (targetPkgSetting != null) {
4344                     if (!comparePackageSignatures(targetPkgSetting,
4345                             pkg.getSigningDetails().getSignatures())) {
4346                         // check reference signature
4347                         if (mPm.mOverlayConfigSignaturePackage == null) {
4348                             throw new PackageManagerException("Overlay "
4349                                     + pkg.getPackageName() + " and target "
4350                                     + pkg.getOverlayTarget() + " signed with"
4351                                     + " different certificates, and the overlay lacks"
4352                                     + " <overlay android:targetName>");
4353                         }
4354                         final PackageSetting refPkgSetting =
4355                                 mPm.mSettings.getPackageLPr(
4356                                         mPm.mOverlayConfigSignaturePackage);
4357                         if (!comparePackageSignatures(refPkgSetting,
4358                                 pkg.getSigningDetails().getSignatures())) {
4359                             throw new PackageManagerException("Overlay "
4360                                     + pkg.getPackageName() + " signed with a different "
4361                                     + "certificate than both the reference package and "
4362                                     + "target " + pkg.getOverlayTarget() + ", and the "
4363                                     + "overlay lacks <overlay android:targetName>");
4364                         }
4365                     }
4366                 }
4367             }
4368         }
4369     }
4370 
assertPackageWithSharedUserIdIsPrivileged(AndroidPackage pkg)4371     private void assertPackageWithSharedUserIdIsPrivileged(AndroidPackage pkg)
4372             throws PackageManagerException {
4373         if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
4374             SharedUserSetting sharedUserSetting = null;
4375             try {
4376                 sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(),
4377                         0, 0, false);
4378             } catch (PackageManagerException ignore) {
4379             }
4380             if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
4381                 // Exempt SharedUsers signed with the platform key.
4382                 PackageSetting platformPkgSetting = mPm.mSettings.getPackageLPr("android");
4383                 if (!comparePackageSignatures(platformPkgSetting,
4384                         pkg.getSigningDetails().getSignatures())) {
4385                     throw new PackageManagerException("Apps that share a user with a "
4386                             + "privileged app must themselves be marked as privileged. "
4387                             + pkg.getPackageName() + " shares privileged user "
4388                             + pkg.getSharedUserId() + ".");
4389                 }
4390             }
4391         }
4392     }
4393 
adjustScanFlags( @ackageManagerService.ScanFlags int scanFlags, PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user, AndroidPackage pkg)4394     private @PackageManagerService.ScanFlags int adjustScanFlags(
4395             @PackageManagerService.ScanFlags int scanFlags,
4396             PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
4397             AndroidPackage pkg) {
4398         scanFlags = ScanPackageUtils.adjustScanFlagsWithPackageSetting(scanFlags, pkgSetting,
4399                 disabledPkgSetting, user);
4400 
4401         // Exception for privileged apps that share a user with a priv-app.
4402         final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
4403                 && ScanPackageUtils.getVendorPartitionVersion() < 28;
4404         if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
4405                 && !pkg.isPrivileged()
4406                 && (pkg.getSharedUserId() != null)
4407                 && !skipVendorPrivilegeScan) {
4408             SharedUserSetting sharedUserSetting = null;
4409             synchronized (mPm.mLock) {
4410                 try {
4411                     sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0,
4412                             0, false);
4413                 } catch (PackageManagerException ignore) {
4414                 }
4415                 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
4416                     // Exempt SharedUsers signed with the platform key.
4417                     // TODO(b/72378145) Fix this exemption. Force signature apps
4418                     // to allowlist their privileged permissions just like other
4419                     // priv-apps.
4420                     PackageSetting platformPkgSetting = mPm.mSettings.getPackageLPr("android");
4421                     if ((compareSignatures(
4422                             platformPkgSetting.getSigningDetails().getSignatures(),
4423                             pkg.getSigningDetails().getSignatures())
4424                             != PackageManager.SIGNATURE_MATCH)) {
4425                         scanFlags |= SCAN_AS_PRIVILEGED;
4426                     }
4427                 }
4428             }
4429         }
4430 
4431         return scanFlags;
4432     }
4433 }
4434