• 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.INSTALL_FAILED_INVALID_APK;
20 import static android.content.pm.PackageManager.INSTALL_FAILED_PROCESS_NOT_DEFINED;
21 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
22 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
23 
24 import static com.android.server.pm.PackageManagerService.DEBUG_ABI_SELECTION;
25 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
26 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
27 import static com.android.server.pm.PackageManagerService.SCAN_AS_APEX;
28 import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP;
29 import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
30 import static com.android.server.pm.PackageManagerService.SCAN_AS_ODM;
31 import static com.android.server.pm.PackageManagerService.SCAN_AS_OEM;
32 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRIVILEGED;
33 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRODUCT;
34 import static com.android.server.pm.PackageManagerService.SCAN_AS_STOPPED_SYSTEM_APP;
35 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM;
36 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM_EXT;
37 import static com.android.server.pm.PackageManagerService.SCAN_AS_VENDOR;
38 import static com.android.server.pm.PackageManagerService.SCAN_AS_VIRTUAL_PRELOAD;
39 import static com.android.server.pm.PackageManagerService.SCAN_BOOTING;
40 import static com.android.server.pm.PackageManagerService.SCAN_DONT_KILL_APP;
41 import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE;
42 import static com.android.server.pm.PackageManagerService.SCAN_MOVE;
43 import static com.android.server.pm.PackageManagerService.SCAN_NEW_INSTALL;
44 import static com.android.server.pm.PackageManagerService.SCAN_NO_DEX;
45 import static com.android.server.pm.PackageManagerService.SCAN_UPDATE_TIME;
46 import static com.android.server.pm.PackageManagerService.TAG;
47 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
48 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
49 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
50 import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
51 
52 import android.annotation.NonNull;
53 import android.annotation.Nullable;
54 import android.content.pm.ApplicationInfo;
55 import android.content.pm.Flags;
56 import android.content.pm.PackageManager;
57 import android.content.pm.SharedLibraryInfo;
58 import android.content.pm.SigningDetails;
59 import android.content.pm.parsing.result.ParseResult;
60 import android.content.pm.parsing.result.ParseTypeImpl;
61 import android.os.Build;
62 import android.os.Environment;
63 import android.os.Process;
64 import android.os.SystemProperties;
65 import android.os.Trace;
66 import android.os.UserHandle;
67 import android.system.Os;
68 import android.system.OsConstants;
69 import android.text.TextUtils;
70 import android.util.ArrayMap;
71 import android.util.ArraySet;
72 import android.util.Log;
73 import android.util.Pair;
74 import android.util.Slog;
75 import android.util.apk.ApkSignatureVerifier;
76 import android.util.jar.StrictJarFile;
77 
78 import com.android.internal.annotations.VisibleForTesting;
79 import com.android.internal.pm.parsing.pkg.ParsedPackage;
80 import com.android.internal.pm.pkg.component.ComponentMutateUtils;
81 import com.android.internal.pm.pkg.component.ParsedActivity;
82 import com.android.internal.pm.pkg.component.ParsedMainComponent;
83 import com.android.internal.pm.pkg.component.ParsedProcess;
84 import com.android.internal.pm.pkg.component.ParsedProvider;
85 import com.android.internal.pm.pkg.component.ParsedService;
86 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
87 import com.android.internal.util.ArrayUtils;
88 import com.android.server.SystemConfig;
89 import com.android.server.pm.parsing.PackageInfoUtils;
90 import com.android.server.pm.parsing.library.PackageBackwardCompatibility;
91 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
92 import com.android.server.pm.pkg.AndroidPackage;
93 import com.android.server.pm.pkg.PackageStateUtils;
94 import com.android.server.utils.WatchedArraySet;
95 
96 import dalvik.system.VMRuntime;
97 
98 import java.io.File;
99 import java.io.IOException;
100 import java.util.ArrayList;
101 import java.util.List;
102 import java.util.Map;
103 import java.util.Objects;
104 import java.util.UUID;
105 
106 /**
107  * Helper class that handles package scanning logic
108  */
109 final class ScanPackageUtils {
110 
111     public static final int PAGE_SIZE_16KB = 16384;
112 
113     /**
114      * Just scans the package without any side effects.
115      *
116      * @param injector injector for acquiring dependencies
117      * @param request Information about the package to be scanned
118      * @param isUnderFactoryTest Whether or not the device is under factory test
119      * @param currentTime The current time, in millis
120      * @return The results of the scan
121      */
122     @VisibleForTesting
123     @NonNull
scanPackageOnly(@onNull ScanRequest request, PackageManagerServiceInjector injector, boolean isUnderFactoryTest, long currentTime)124     public static ScanResult scanPackageOnly(@NonNull ScanRequest request,
125             PackageManagerServiceInjector injector,
126             boolean isUnderFactoryTest, long currentTime)
127             throws PackageManagerException {
128         final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
129         ParsedPackage parsedPackage = request.mParsedPackage;
130         PackageSetting pkgSetting = request.mPkgSetting;
131         final PackageSetting disabledPkgSetting = request.mDisabledPkgSetting;
132         final PackageSetting originalPkgSetting = request.mOriginalPkgSetting;
133         final @ParsingPackageUtils.ParseFlags int parseFlags = request.mParseFlags;
134         final @PackageManagerService.ScanFlags int scanFlags = request.mScanFlags;
135         final String realPkgName = request.mRealPkgName;
136         final SharedUserSetting oldSharedUserSetting = request.mOldSharedUserSetting;
137         final SharedUserSetting sharedUserSetting = request.mSharedUserSetting;
138         final UserHandle user = request.mUser;
139         final boolean isPlatformPackage = request.mIsPlatformPackage;
140 
141         List<String> changedAbiCodePath = null;
142 
143         if (DEBUG_PACKAGE_SCANNING) {
144             if ((parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0) {
145                 Log.d(TAG, "Scanning package " + parsedPackage.getPackageName());
146             }
147         }
148 
149         // Initialize package source and resource directories
150         final File destCodeFile = new File(parsedPackage.getPath());
151 
152         // We keep references to the derived CPU Abis from settings in oder to reuse
153         // them in the case where we're not upgrading or booting for the first time.
154         String primaryCpuAbiFromSettings = null;
155         String secondaryCpuAbiFromSettings = null;
156         boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
157         boolean isApex = (scanFlags & SCAN_AS_APEX) != 0;
158 
159         if (!needToDeriveAbi) {
160             if (pkgSetting != null) {
161                 // TODO(b/154610922): if it is not first boot or upgrade, we should directly use
162                 // API info from existing package setting. However, stub packages currently do not
163                 // preserve ABI info, thus the special condition check here. Remove the special
164                 // check after we fix the stub generation.
165                 if (pkgSetting.getPkg() != null && pkgSetting.getPkg().isStub()) {
166                     needToDeriveAbi = true;
167                 } else {
168                     primaryCpuAbiFromSettings = pkgSetting.getPrimaryCpuAbiLegacy();
169                     secondaryCpuAbiFromSettings = pkgSetting.getSecondaryCpuAbiLegacy();
170                 }
171             } else {
172                 // Re-scanning a system package after uninstalling updates; need to derive ABI
173                 needToDeriveAbi = true;
174             }
175         }
176 
177         boolean isPendingRestoreBefore = false;
178         if (pkgSetting != null && oldSharedUserSetting != sharedUserSetting) {
179             PackageManagerService.reportSettingsProblem(Log.WARN,
180                     "Package " + parsedPackage.getPackageName() + " shared user changed from "
181                             + (oldSharedUserSetting != null
182                             ? oldSharedUserSetting.name : "<nothing>")
183                             + " to "
184                             + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
185                             + "; replacing with new");
186             // Preserve the value of isPendingRestore. We need to set it to the new PackageSetting
187             // if the value is true to restore the app
188             isPendingRestoreBefore = pkgSetting.isPendingRestore();
189             pkgSetting = null;
190         }
191 
192         String[] usesSdkLibraries = null;
193         if (!parsedPackage.getUsesSdkLibraries().isEmpty()) {
194             usesSdkLibraries = new String[parsedPackage.getUsesSdkLibraries().size()];
195             parsedPackage.getUsesSdkLibraries().toArray(usesSdkLibraries);
196         }
197 
198         String[] usesStaticLibraries = null;
199         if (!parsedPackage.getUsesStaticLibraries().isEmpty()) {
200             usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()];
201             parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries);
202         }
203 
204         final UUID newDomainSetId = injector.getDomainVerificationManagerInternal().generateNewId();
205 
206         // TODO(b/135203078): Remove appInfoFlag usage in favor of individually assigned booleans
207         //  to avoid adding something that's unsupported due to lack of state, since it's called
208         //  with null.
209         final boolean createNewPackage = (pkgSetting == null);
210         if (createNewPackage) {
211             final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
212             final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
213             final boolean isStoppedSystemApp = (scanFlags & SCAN_AS_STOPPED_SYSTEM_APP) != 0;
214 
215             // Flags contain system values stored in the server variant of AndroidPackage,
216             // and so the server-side PackageInfoUtils is still called, even without a
217             // PackageSetting to pass in.
218             int pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, null);
219             int pkgPrivateFlags = PackageInfoUtils.appInfoPrivateFlags(parsedPackage, null);
220 
221             // REMOVE SharedUserSetting from method; update in a separate call
222             pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),
223                     originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting,
224                     destCodeFile, parsedPackage.getNativeLibraryRootDir(),
225                     AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage),
226                     AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage),
227                     parsedPackage.getLongVersionCode(), pkgFlags, pkgPrivateFlags, user,
228                     true /*allowInstall*/, instantApp, virtualPreload, isStoppedSystemApp,
229                     UserManagerService.getInstance(), usesSdkLibraries,
230                     parsedPackage.getUsesSdkLibrariesVersionsMajor(),
231                     parsedPackage.getUsesSdkLibrariesOptional(), usesStaticLibraries,
232                     parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(),
233                     newDomainSetId,
234                     parsedPackage.getTargetSdkVersion(), parsedPackage.getRestrictUpdateHash());
235 
236             // If isPendingRestore is true before, set the value true to the PackageSetting
237             if (isPendingRestoreBefore) {
238                 pkgSetting.setPendingRestore(true);
239             }
240         } else {
241             // make a deep copy to avoid modifying any existing system state.
242             pkgSetting = new PackageSetting(pkgSetting);
243             pkgSetting.setPkg(parsedPackage);
244             final boolean isDontKill = (scanFlags & SCAN_DONT_KILL_APP) != 0;
245 
246             // REMOVE SharedUserSetting from method; update in a separate call.
247             //
248             // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
249             // secondaryCpuAbi are not known at this point so we always update them
250             // to null here, only to reset them at a later point.
251             Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, oldSharedUserSetting,
252                     sharedUserSetting, destCodeFile, parsedPackage.getNativeLibraryDir(),
253                     pkgSetting.getPrimaryCpuAbi(),
254                     pkgSetting.getSecondaryCpuAbi(),
255                     PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
256                     PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting),
257                     UserManagerService.getInstance(),
258                     usesSdkLibraries, parsedPackage.getUsesSdkLibrariesVersionsMajor(),
259                     parsedPackage.getUsesSdkLibrariesOptional(),
260                     usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
261                     parsedPackage.getMimeGroups(), newDomainSetId,
262                     parsedPackage.getTargetSdkVersion(), parsedPackage.getRestrictUpdateHash(),
263                     isDontKill);
264         }
265 
266         if (createNewPackage && originalPkgSetting != null) {
267             // This is the initial transition from the original package, so,
268             // fix up the new package's name now. We must do this after looking
269             // up the package under its new name, so getPackageLP takes care of
270             // fiddling things correctly.
271             parsedPackage.setPackageName(originalPkgSetting.getPackageName());
272 
273             // File a report about this.
274             String msg = "New package " + pkgSetting.getRealName()
275                     + " renamed to replace old package " + pkgSetting.getPackageName();
276             PackageManagerService.reportSettingsProblem(Log.WARN, msg);
277         }
278 
279         final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
280         // for existing packages, change the install state; but, only if it's explicitly specified
281         if (!createNewPackage) {
282             final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
283             final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
284             setInstantAppForUser(injector, pkgSetting, userId, instantApp, fullApp);
285         }
286         // TODO(patb): see if we can do away with disabled check here.
287         if (disabledPkgSetting != null
288                 || (0 != (scanFlags & SCAN_NEW_INSTALL)
289                 && pkgSetting != null && pkgSetting.isSystem())) {
290             pkgSetting.getPkgState().setUpdatedSystemApp(true);
291         }
292 
293         pkgSetting.getTransientState().setSeInfo(SELinuxMMAC.getSeInfo(pkgSetting, parsedPackage,
294                 sharedUserSetting, injector.getCompatibility()));
295 
296         if (pkgSetting.isSystem()) {
297             configurePackageComponents(parsedPackage);
298         }
299 
300         final String cpuAbiOverride = deriveAbiOverride(request.mCpuAbiOverride);
301         final boolean isSystemApp = pkgSetting.isSystem();
302         final boolean isUpdatedSystemApp = pkgSetting.isUpdatedSystemApp();
303 
304         final File appLib32InstallDir = getAppLib32InstallDir();
305         // The native libs of Apex is located in apex_payload.img, don't need to parse it from
306         // the original apex file
307         if (!isApex) {
308             if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
309                 if (needToDeriveAbi) {
310                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
311                     try {
312                         final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
313                                 derivedAbi =
314                                 packageAbiHelper.derivePackageAbi(
315                                         parsedPackage,
316                                         isSystemApp,
317                                         isUpdatedSystemApp,
318                                         cpuAbiOverride,
319                                         appLib32InstallDir);
320                         derivedAbi.first.applyTo(parsedPackage);
321                         derivedAbi.second.applyTo(parsedPackage);
322                     } finally {
323                         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
324                     }
325 
326                     // Some system apps still use directory structure for native libraries
327                     // in which case we might end up not detecting abi solely based on apk
328                     // structure. Try to detect abi based on directory structure.
329 
330                     String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi(
331                             parsedPackage);
332                     if (isSystemApp && !isUpdatedSystemApp && pkgRawPrimaryCpuAbi == null) {
333                         final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
334                                 parsedPackage);
335                         abis.applyTo(parsedPackage);
336                         abis.applyTo(pkgSetting);
337                         final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
338                                 packageAbiHelper.deriveNativeLibraryPaths(parsedPackage,
339                                         isSystemApp, isUpdatedSystemApp, appLib32InstallDir);
340                         nativeLibraryPaths.applyTo(parsedPackage);
341                     }
342                 } else {
343                     // This is not a first boot or an upgrade, don't bother deriving the
344                     // ABI during the scan. Instead, trust the value that was stored in the
345                     // package setting.
346                     parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings)
347                             .setSecondaryCpuAbi(secondaryCpuAbiFromSettings);
348 
349                     final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
350                             packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isSystemApp,
351                                     isUpdatedSystemApp, appLib32InstallDir);
352                     nativeLibraryPaths.applyTo(parsedPackage);
353 
354                     if (DEBUG_ABI_SELECTION) {
355                         Slog.i(TAG, "Using ABIS and native lib paths from settings : "
356                                 + parsedPackage.getPackageName() + " "
357                                 + AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage)
358                                 + ", "
359                                 + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage));
360                     }
361                 }
362             } else {
363                 if ((scanFlags & SCAN_MOVE) != 0) {
364                     // We haven't run dex-opt for this move (since we've moved the compiled output
365                     // too) but we already have this packages package info in the PackageSetting.
366                     // We just use that and derive the native library path based on the new code
367                     // path.
368                     parsedPackage.setPrimaryCpuAbi(pkgSetting.getPrimaryCpuAbiLegacy())
369                             .setSecondaryCpuAbi(pkgSetting.getSecondaryCpuAbiLegacy());
370                 }
371 
372                 // Set native library paths again. For moves, the path will be updated based on the
373                 // ABIs we've determined above. For non-moves, the path will be updated based on the
374                 // ABIs we determined during compilation, but the path will depend on the final
375                 // package path (after the rename away from the stage path).
376                 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
377                         packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isSystemApp,
378                                 isUpdatedSystemApp, appLib32InstallDir);
379                 nativeLibraryPaths.applyTo(parsedPackage);
380             }
381 
382             // This is a special case for the "system" package, where the ABI is
383             // dictated by the zygote configuration (and init.rc). We should keep track
384             // of this ABI so that we can deal with "normal" applications that run under
385             // the same UID correctly.
386             if (isPlatformPackage) {
387                 parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit()
388                         ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]);
389             }
390         }
391 
392         // If there's a mismatch between the abi-override in the package setting
393         // and the abiOverride specified for the install. Warn about this because we
394         // would've already compiled the app without taking the package setting into
395         // account.
396         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
397             if (cpuAbiOverride == null) {
398                 Slog.w(TAG, "Ignoring persisted ABI override for package "
399                         + parsedPackage.getPackageName());
400             }
401         }
402 
403         pkgSetting.setPrimaryCpuAbi(AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage))
404                 .setSecondaryCpuAbi(AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage))
405                 .setCpuAbiOverride(cpuAbiOverride);
406 
407         if (DEBUG_ABI_SELECTION) {
408             Slog.d(TAG, "Resolved nativeLibraryRoot for " + parsedPackage.getPackageName()
409                     + " to root=" + parsedPackage.getNativeLibraryRootDir()
410                     + ", to dir=" + parsedPackage.getNativeLibraryDir()
411                     + ", isa=" + parsedPackage.isNativeLibraryRootRequiresIsa());
412         }
413 
414         // Push the derived path down into PackageSettings so we know what to
415         // clean up at uninstall time.
416         pkgSetting.setLegacyNativeLibraryPath(parsedPackage.getNativeLibraryRootDir());
417 
418         if (DEBUG_ABI_SELECTION) {
419             Log.d(TAG, "Abis for package[" + parsedPackage.getPackageName() + "] are"
420                     + " primary=" + pkgSetting.getPrimaryCpuAbiLegacy()
421                     + " secondary=" + pkgSetting.getSecondaryCpuAbiLegacy()
422                     + " abiOverride=" + pkgSetting.getCpuAbiOverride());
423         }
424 
425         boolean is16KbDevice = Os.sysconf(OsConstants._SC_PAGESIZE) == PAGE_SIZE_16KB;
426         if (Flags.appCompatOption16kb() && is16KbDevice) {
427             // Alignment checks are used decide whether this app should run in compat mode when
428             // nothing was specified in manifest. Manifest should always take precedence over
429             // something decided by platform.
430             if (parsedPackage.getPageSizeAppCompatFlags()
431                     > ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED) {
432                 pkgSetting.setPageSizeAppCompatFlags(parsedPackage.getPageSizeAppCompatFlags());
433             } else {
434                 // 16 KB is only support for 64 bit ABIs and for apps which are being installed
435                 // Check alignment. System, Apex and Platform packages should be page-agnostic now
436                 if ((Build.SUPPORTED_64_BIT_ABIS.length > 0)
437                         && !isSystemApp
438                         && !isApex
439                         && !isPlatformPackage) {
440                     int mode =
441                             packageAbiHelper.checkPackageAlignment(
442                                     parsedPackage,
443                                     pkgSetting.getLegacyNativeLibraryPath(),
444                                     parsedPackage.isNativeLibraryRootRequiresIsa(),
445                                     pkgSetting.getCpuAbiOverride());
446                     if (mode >= ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED) {
447                         pkgSetting.setPageSizeAppCompatFlags(mode);
448                     } else {
449                         Slog.e(TAG, "Error occurred while checking alignment of package : "
450                                 + parsedPackage.getPackageName());
451                     }
452                 }
453             }
454         }
455 
456         if ((scanFlags & SCAN_BOOTING) == 0 && oldSharedUserSetting != null) {
457             // We don't do this here during boot because we can do it all
458             // at once after scanning all existing packages.
459             //
460             // We also do this *before* we perform dexopt on this package, so that
461             // we can avoid redundant dexopts, and also to make sure we've got the
462             // code and package path correct.
463             changedAbiCodePath = applyAdjustedAbiToSharedUser(oldSharedUserSetting,
464                     parsedPackage, packageAbiHelper.getAdjustedAbiForSharedUser(
465                             oldSharedUserSetting.getPackageStates(), parsedPackage));
466         }
467 
468         parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions()
469                 .contains(android.Manifest.permission.FACTORY_TEST));
470 
471         if (isSystemApp) {
472             pkgSetting.setIsOrphaned(true);
473         }
474 
475         // update debuggable and BaseRevisionCode to packageSetting
476         pkgSetting.setDebuggable(parsedPackage.isDebuggable());
477         pkgSetting.setBaseRevisionCode(parsedPackage.getBaseRevisionCode());
478 
479         // Take care of first install / last update times.
480         final long scanFileTime = getLastModifiedTime(parsedPackage);
481         final long earliestFirstInstallTime =
482                 PackageStateUtils.getEarliestFirstInstallTime((pkgSetting.getUserStates()));
483         if (currentTime != 0) {
484             if (earliestFirstInstallTime == 0) {
485                 pkgSetting.setFirstInstallTime(currentTime, userId)
486                         .setLastUpdateTime(currentTime);
487             } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
488                 pkgSetting.setLastUpdateTime(currentTime);
489             }
490         } else if (earliestFirstInstallTime == 0) {
491             // We need *something*.  Take time stamp of the file.
492             pkgSetting.setFirstInstallTime(scanFileTime, userId)
493                     .setLastUpdateTime(scanFileTime);
494         } else if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0) {
495             if (scanFileTime != pkgSetting.getLastModifiedTime()) {
496                 // A package on the system image has changed; consider this
497                 // to be an update.
498                 pkgSetting.setLastUpdateTime(scanFileTime);
499             }
500         }
501         pkgSetting.setLastModifiedTime(scanFileTime);
502         // TODO(b/135203078): Remove, move to constructor
503         pkgSetting.setPkg(parsedPackage)
504                 .setFlags(PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting))
505                 .setPrivateFlags(PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting));
506         if (parsedPackage.getLongVersionCode() != pkgSetting.getVersionCode()) {
507             pkgSetting.setLongVersionCode(parsedPackage.getLongVersionCode());
508         }
509         // Update volume if needed
510         final String volumeUuid = parsedPackage.getVolumeUuid();
511         if (!Objects.equals(volumeUuid, pkgSetting.getVolumeUuid())) {
512             Slog.i(PackageManagerService.TAG,
513                     "Update" + (pkgSetting.isSystem() ? " system" : "")
514                             + " package " + parsedPackage.getPackageName()
515                             + " volume from " + pkgSetting.getVolumeUuid()
516                             + " to " + volumeUuid);
517             pkgSetting.setVolumeUuid(volumeUuid);
518         }
519         pkgSetting.setLeavingSharedUser(parsedPackage.isLeavingSharedUser());
520 
521         SharedLibraryInfo sdkLibraryInfo = null;
522         if (!TextUtils.isEmpty(parsedPackage.getSdkLibraryName())) {
523             sdkLibraryInfo = AndroidPackageUtils.createSharedLibraryForSdk(parsedPackage);
524         }
525         SharedLibraryInfo staticSharedLibraryInfo = null;
526         if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibraryName())) {
527             staticSharedLibraryInfo =
528                     AndroidPackageUtils.createSharedLibraryForStatic(parsedPackage);
529         }
530         List<SharedLibraryInfo> dynamicSharedLibraryInfos = null;
531         if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) {
532             dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size());
533             for (String name : parsedPackage.getLibraryNames()) {
534                 dynamicSharedLibraryInfos.add(
535                         AndroidPackageUtils.createSharedLibraryForDynamic(parsedPackage, name));
536             }
537         }
538 
539         return new ScanResult(request, pkgSetting, changedAbiCodePath,
540                 !createNewPackage /* existingSettingCopied */,
541                 Process.INVALID_UID /* previousAppId */ , sdkLibraryInfo,
542                 staticSharedLibraryInfo, dynamicSharedLibraryInfos);
543     }
544 
545     /**
546      * Returns the actual scan flags depending upon the state of the other settings.
547      * <p>Updated system applications will not have the following flags set
548      * by default and need to be adjusted after the fact:
549      * <ul>
550      * <li>{@link PackageManagerService.SCAN_AS_SYSTEM}</li>
551      * <li>{@link PackageManagerService.SCAN_AS_PRIVILEGED}</li>
552      * <li>{@link PackageManagerService.SCAN_AS_OEM}</li>
553      * <li>{@link PackageManagerService.SCAN_AS_VENDOR}</li>
554      * <li>{@link PackageManagerService.SCAN_AS_PRODUCT}</li>
555      * <li>{@link PackageManagerService.SCAN_AS_SYSTEM_EXT}</li>
556      * <li>{@link PackageManagerService.SCAN_AS_INSTANT_APP}</li>
557      * <li>{@link PackageManagerService.SCAN_AS_VIRTUAL_PRELOAD}</li>
558      * <li>{@link PackageManagerService.SCAN_AS_ODM}</li>
559      * </ul>
560      */
adjustScanFlagsWithPackageSetting( @ackageManagerService.ScanFlags int scanFlags, PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user)561     public static @PackageManagerService.ScanFlags int adjustScanFlagsWithPackageSetting(
562             @PackageManagerService.ScanFlags int scanFlags,
563             PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user) {
564 
565         // TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain
566         // the correct isSystem value now that we don't disable system packages before scan.
567         final PackageSetting systemPkgSetting =
568                 (scanFlags & SCAN_NEW_INSTALL) != 0 && disabledPkgSetting == null
569                         && pkgSetting != null && pkgSetting.isSystem()
570                         ? pkgSetting
571                         : disabledPkgSetting;
572         if (systemPkgSetting != null)  {
573             // updated system application, must at least have SCAN_AS_SYSTEM
574             scanFlags |= SCAN_AS_SYSTEM;
575             if ((systemPkgSetting.getPrivateFlags()
576                     & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
577                 scanFlags |= SCAN_AS_PRIVILEGED;
578             }
579             if ((systemPkgSetting.getPrivateFlags()
580                     & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
581                 scanFlags |= SCAN_AS_OEM;
582             }
583             if ((systemPkgSetting.getPrivateFlags()
584                     & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
585                 scanFlags |= SCAN_AS_VENDOR;
586             }
587             if ((systemPkgSetting.getPrivateFlags()
588                     & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
589                 scanFlags |= SCAN_AS_PRODUCT;
590             }
591             if ((systemPkgSetting.getPrivateFlags()
592                     & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
593                 scanFlags |= SCAN_AS_SYSTEM_EXT;
594             }
595             if ((systemPkgSetting.getPrivateFlags()
596                     & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
597                 scanFlags |= SCAN_AS_ODM;
598             }
599         }
600         if (pkgSetting != null) {
601             final int userId = ((user == null) ? 0 : user.getIdentifier());
602             if (pkgSetting.getInstantApp(userId)) {
603                 scanFlags |= SCAN_AS_INSTANT_APP;
604             }
605             if (pkgSetting.getVirtualPreload(userId)) {
606                 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
607             }
608         }
609 
610         return scanFlags;
611     }
612 
613     /**
614      * Enforces code policy for the package. This ensures that if an APK has
615      * declared hasCode="true" in its manifest that the APK actually contains
616      * code.
617      *
618      * @throws PackageManagerException If bytecode could not be found when it should exist
619      */
assertCodePolicy(AndroidPackage pkg)620     public static void assertCodePolicy(AndroidPackage pkg)
621             throws PackageManagerException {
622         final boolean shouldHaveCode = pkg.isDeclaredHavingCode();
623         if (shouldHaveCode && !apkHasCode(pkg.getBaseApkPath())) {
624             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
625                     "Package " + pkg.getBaseApkPath() + " code is missing");
626         }
627 
628         if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) {
629             for (int i = 0; i < pkg.getSplitCodePaths().length; i++) {
630                 final boolean splitShouldHaveCode =
631                         (pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
632                 if (splitShouldHaveCode && !apkHasCode(pkg.getSplitCodePaths()[i])) {
633                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
634                             "Package " + pkg.getSplitCodePaths()[i] + " code is missing");
635                 }
636             }
637         }
638     }
639 
assertStaticSharedLibraryIsValid(AndroidPackage pkg, @PackageManagerService.ScanFlags int scanFlags)640     public static void assertStaticSharedLibraryIsValid(AndroidPackage pkg,
641             @PackageManagerService.ScanFlags int scanFlags) throws PackageManagerException {
642         // Static shared libraries should have at least O target SDK
643         if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
644             throw PackageManagerException.ofInternalError(
645                     "Packages declaring static-shared libs must target O SDK or higher",
646                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_LOW_SDK);
647         }
648 
649         // Package declaring static a shared lib cannot be instant apps
650         if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
651             throw PackageManagerException.ofInternalError(
652                     "Packages declaring static-shared libs cannot be instant apps",
653                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_INSTANT);
654         }
655 
656         // Package declaring static a shared lib cannot be renamed since the package
657         // name is synthetic and apps can't code around package manager internals.
658         if (!ArrayUtils.isEmpty(pkg.getOriginalPackages())) {
659             throw PackageManagerException.ofInternalError(
660                     "Packages declaring static-shared libs cannot be renamed",
661                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_RENAMED);
662         }
663 
664         // Package declaring static a shared lib cannot declare dynamic libs
665         if (!ArrayUtils.isEmpty(pkg.getLibraryNames())) {
666             throw PackageManagerException.ofInternalError(
667                     "Packages declaring static-shared libs cannot declare dynamic libs",
668                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_DYNAMIC);
669         }
670 
671         // Package declaring static a shared lib cannot declare shared users
672         if (pkg.getSharedUserId() != null) {
673             throw PackageManagerException.ofInternalError(
674                     "Packages declaring static-shared libs cannot declare shared users",
675                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_SHARED_USER);
676         }
677 
678         // Static shared libs cannot declare activities
679         if (!pkg.getActivities().isEmpty()) {
680             throw PackageManagerException.ofInternalError(
681                     "Static shared libs cannot declare activities",
682                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_ACTIVITY);
683         }
684 
685         // Static shared libs cannot declare services
686         if (!pkg.getServices().isEmpty()) {
687             throw PackageManagerException.ofInternalError(
688                     "Static shared libs cannot declare services",
689                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_SERVICE);
690         }
691 
692         // Static shared libs cannot declare providers
693         if (!pkg.getProviders().isEmpty()) {
694             throw PackageManagerException.ofInternalError(
695                     "Static shared libs cannot declare content providers",
696                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_CONTENT_PROVIDER);
697         }
698 
699         // Static shared libs cannot declare receivers
700         if (!pkg.getReceivers().isEmpty()) {
701             throw PackageManagerException.ofInternalError(
702                     "Static shared libs cannot declare broadcast receivers",
703                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_BROADCAST_RECEIVER);
704         }
705 
706         // Static shared libs cannot declare permission groups
707         if (!pkg.getPermissionGroups().isEmpty()) {
708             throw PackageManagerException.ofInternalError(
709                     "Static shared libs cannot declare permission groups",
710                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_PERMISSION_GROUP);
711         }
712 
713         // Static shared libs cannot declare attributions
714         if (!pkg.getAttributions().isEmpty()) {
715             throw PackageManagerException.ofInternalError(
716                     "Static shared libs cannot declare features",
717                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_FEATURE);
718         }
719 
720         // Static shared libs cannot declare permissions
721         if (!pkg.getPermissions().isEmpty()) {
722             throw PackageManagerException.ofInternalError(
723                     "Static shared libs cannot declare permissions",
724                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_PERMISSION);
725         }
726 
727         // Static shared libs cannot declare protected broadcasts
728         if (!pkg.getProtectedBroadcasts().isEmpty()) {
729             throw PackageManagerException.ofInternalError(
730                     "Static shared libs cannot declare protected broadcasts",
731                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_PROTECTED_BROADCAST);
732         }
733 
734         // Static shared libs cannot be overlay targets
735         if (pkg.getOverlayTarget() != null) {
736             throw PackageManagerException.ofInternalError(
737                     "Static shared libs cannot be overlay targets",
738                     PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_OVERLAY_TARGETS);
739         }
740     }
741 
assertProcessesAreValid(AndroidPackage pkg)742     public static void assertProcessesAreValid(AndroidPackage pkg) throws PackageManagerException {
743         final Map<String, ParsedProcess> procs = pkg.getProcesses();
744         if (!procs.isEmpty()) {
745             if (!procs.containsKey(pkg.getProcessName())) {
746                 throw new PackageManagerException(
747                         INSTALL_FAILED_PROCESS_NOT_DEFINED,
748                         "Can't install because application tag's process attribute "
749                                 + pkg.getProcessName()
750                                 + " (in package " + pkg.getPackageName()
751                                 + ") is not included in the <processes> list");
752             }
753             assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity");
754             assertPackageProcesses(pkg, pkg.getServices(), procs, "service");
755             assertPackageProcesses(pkg, pkg.getReceivers(), procs, "receiver");
756             assertPackageProcesses(pkg, pkg.getProviders(), procs, "provider");
757         }
758     }
759 
assertPackageProcesses(AndroidPackage pkg, List<T> components, Map<String, ParsedProcess> procs, String compName)760     private static <T extends ParsedMainComponent> void assertPackageProcesses(AndroidPackage pkg,
761             List<T> components, Map<String, ParsedProcess> procs, String compName)
762             throws PackageManagerException {
763         if (components == null) {
764             return;
765         }
766         for (int i = components.size() - 1; i >= 0; i--) {
767             final ParsedMainComponent component = components.get(i);
768             if (!procs.containsKey(component.getProcessName())) {
769                 throw new PackageManagerException(
770                         INSTALL_FAILED_PROCESS_NOT_DEFINED,
771                         "Can't install because " + compName + " " + component.getClassName()
772                                 + "'s process attribute " + component.getProcessName()
773                                 + " (in package " + pkg.getPackageName()
774                                 + ") is not included in the <processes> list");
775             }
776         }
777     }
778 
assertMinSignatureSchemeIsValid(AndroidPackage pkg, @ParsingPackageUtils.ParseFlags int parseFlags)779     public static void assertMinSignatureSchemeIsValid(AndroidPackage pkg,
780             @ParsingPackageUtils.ParseFlags int parseFlags) throws PackageManagerException {
781         int minSignatureSchemeVersion =
782                 ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
783                         pkg.getTargetSdkVersion());
784         if (pkg.getSigningDetails().getSignatureSchemeVersion()
785                 < minSignatureSchemeVersion) {
786             throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
787                     "No signature found in package of version " + minSignatureSchemeVersion
788                             + " or newer for package " + pkg.getPackageName());
789         }
790     }
791 
792     /**
793      * Returns the "real" name of the package.
794      * <p>This may differ from the package's actual name if the application has already
795      * been installed under one of this package's original names.
796      */
getRealPackageName(@onNull AndroidPackage pkg, @Nullable String renamedPkgName, boolean isSystemApp)797     public static @Nullable String getRealPackageName(@NonNull AndroidPackage pkg,
798             @Nullable String renamedPkgName, boolean isSystemApp) {
799         if (isPackageRenamed(pkg, renamedPkgName)) {
800             return AndroidPackageUtils.getRealPackageOrNull(pkg, isSystemApp);
801         }
802         return null;
803     }
804 
805     /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
isPackageRenamed(@onNull AndroidPackage pkg, @Nullable String renamedPkgName)806     public static boolean isPackageRenamed(@NonNull AndroidPackage pkg,
807             @Nullable String renamedPkgName) {
808         return pkg.getOriginalPackages().contains(renamedPkgName);
809     }
810 
811     /**
812      * Renames the package if it was installed under a different name.
813      * <p>When we've already installed the package under an original name, update
814      * the new package so we can continue to have the old name.
815      */
ensurePackageRenamed(@onNull ParsedPackage parsedPackage, @NonNull String renamedPackageName)816     public static void ensurePackageRenamed(@NonNull ParsedPackage parsedPackage,
817             @NonNull String renamedPackageName) {
818         if (!parsedPackage.getOriginalPackages().contains(renamedPackageName)
819                 || parsedPackage.getPackageName().equals(renamedPackageName)) {
820             return;
821         }
822         parsedPackage.setPackageName(renamedPackageName);
823     }
824 
825     /**
826      * Returns {@code true} if the given file contains code. Otherwise {@code false}.
827      */
apkHasCode(String fileName)828     public static boolean apkHasCode(String fileName) {
829         StrictJarFile jarFile = null;
830         try {
831             jarFile = new StrictJarFile(fileName,
832                     false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
833             return jarFile.findEntry("classes.dex") != null;
834         } catch (IOException ignore) {
835         } finally {
836             try {
837                 if (jarFile != null) {
838                     jarFile.close();
839                 }
840             } catch (IOException ignore) {
841             }
842         }
843         return false;
844     }
845 
846     /**
847      * Sets the enabled state of components configured through {@link SystemConfig}.
848      * This modifies the {@link PackageSetting} object.
849      *
850      * TODO(b/135203078): Move this to package parsing
851      **/
configurePackageComponents(AndroidPackage pkg)852     public static void configurePackageComponents(AndroidPackage pkg) {
853         final ArrayMap<String, Boolean> componentsEnabledStates = SystemConfig.getInstance()
854                 .getComponentsEnabledStates(pkg.getPackageName());
855         if (componentsEnabledStates == null) {
856             return;
857         }
858 
859         for (int i = ArrayUtils.size(pkg.getActivities()) - 1; i >= 0; i--) {
860             final ParsedActivity component = pkg.getActivities().get(i);
861             final Boolean enabled = componentsEnabledStates.get(component.getName());
862             if (enabled != null) {
863                 ComponentMutateUtils.setEnabled(component, enabled);
864             }
865         }
866 
867         for (int i = ArrayUtils.size(pkg.getReceivers()) - 1; i >= 0; i--) {
868             final ParsedActivity component = pkg.getReceivers().get(i);
869             final Boolean enabled = componentsEnabledStates.get(component.getName());
870             if (enabled != null) {
871                 ComponentMutateUtils.setEnabled(component, enabled);
872             }
873         }
874 
875         for (int i = ArrayUtils.size(pkg.getProviders()) - 1; i >= 0; i--) {
876             final ParsedProvider component = pkg.getProviders().get(i);
877             final Boolean enabled = componentsEnabledStates.get(component.getName());
878             if (enabled != null) {
879                 ComponentMutateUtils.setEnabled(component, enabled);
880             }
881         }
882 
883         for (int i = ArrayUtils.size(pkg.getServices()) - 1; i >= 0; i--) {
884             final ParsedService component = pkg.getServices().get(i);
885             final Boolean enabled = componentsEnabledStates.get(component.getName());
886             if (enabled != null) {
887                 ComponentMutateUtils.setEnabled(component, enabled);
888             }
889         }
890     }
891 
getVendorPartitionVersion()892     public static int getVendorPartitionVersion() {
893         final String version = SystemProperties.get("ro.vndk.version");
894         if (!version.isEmpty()) {
895             try {
896                 return Integer.parseInt(version);
897             } catch (NumberFormatException ignore) {
898                 if (ArrayUtils.contains(Build.VERSION.ACTIVE_CODENAMES, version)) {
899                     return Build.VERSION_CODES.CUR_DEVELOPMENT;
900                 }
901             }
902         }
903         return Build.VERSION_CODES.P;
904     }
905 
906     /**
907      * Applies policy to the parsed package based upon the given policy flags.
908      * Ensures the package is in a good state.
909      * <p>
910      * Implementation detail: This method must NOT have any side effect. It would
911      * ideally be static, but, it requires locks to read system state.
912      */
applyPolicy(ParsedPackage parsedPackage, final @PackageManagerService.ScanFlags int scanFlags, @Nullable AndroidPackage platformPkg, boolean isUpdatedSystemApp)913     public static void applyPolicy(ParsedPackage parsedPackage,
914             final @PackageManagerService.ScanFlags int scanFlags,
915             @Nullable AndroidPackage platformPkg, boolean isUpdatedSystemApp) {
916         // TODO: In the real APIs, an updated system app is always a system app, but that may not
917         //  hold true during scan because PMS doesn't propagate the SCAN_AS_SYSTEM flag for the data
918         //  directory. This tries to emulate that behavior by using either the flag or the boolean,
919         //  but this logic is fragile. Specifically, it may affect the PackageBackwardCompatibility
920         //  checker, which switches branches based on whether an app is a system app. When install
921         //  is refactored, the scan policy flags should not be read this late and instead passed
922         //  around in the PackageSetting or a temporary object which infers these values early, so
923         //  that all further consumers agree on their values.
924         boolean isSystemApp = isUpdatedSystemApp;
925         if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
926             isSystemApp = true;
927             parsedPackage.setSystem(true);
928             // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
929             //  is set during parse.
930             if (parsedPackage.isDirectBootAware()) {
931                 parsedPackage.setAllComponentsDirectBootAware(true);
932             }
933             if (compressedFileExists(parsedPackage.getPath())) {
934                 parsedPackage.setStub(true);
935             }
936         } else {
937             parsedPackage
938                     // Non system apps cannot mark any broadcast as protected
939                     .clearProtectedBroadcasts()
940                     // non system apps can't be flagged as core
941                     .setCoreApp(false)
942                     // clear flags not applicable to regular apps
943                     .setPersistent(false)
944                     .setDefaultToDeviceProtectedStorage(false)
945                     .setDirectBootAware(false)
946                     // non system apps can't have permission priority
947                     .capPermissionPriorities();
948         }
949         if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
950             parsedPackage
951                     .markNotActivitiesAsNotExportedIfSingleUser();
952         }
953 
954         parsedPackage.setApex((scanFlags & SCAN_AS_APEX) != 0);
955 
956         parsedPackage.setPrivileged((scanFlags & SCAN_AS_PRIVILEGED) != 0)
957                 .setOem((scanFlags & SCAN_AS_OEM) != 0)
958                 .setVendor((scanFlags & SCAN_AS_VENDOR) != 0)
959                 .setProduct((scanFlags & SCAN_AS_PRODUCT) != 0)
960                 .setSystemExt((scanFlags & SCAN_AS_SYSTEM_EXT) != 0)
961                 .setOdm((scanFlags & SCAN_AS_ODM) != 0);
962 
963         // Check if the package is signed with the same key as the platform package.
964         parsedPackage.setSignedWithPlatformKey(
965                 (PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())
966                         || (platformPkg != null && compareSignatures(
967                         platformPkg.getSigningDetails(),
968                         parsedPackage.getSigningDetails()
969                 ) == PackageManager.SIGNATURE_MATCH))
970         );
971 
972         if (!isSystemApp) {
973             // Only system apps can use these features.
974             parsedPackage.clearOriginalPackages()
975                     .clearAdoptPermissions();
976         }
977 
978         PackageBackwardCompatibility.modifySharedLibraries(parsedPackage, isSystemApp,
979                 isUpdatedSystemApp);
980     }
981 
982     /**
983      * Applies the adjusted ABI calculated by
984      * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(ArraySet, AndroidPackage)} to all
985      * relevant packages and settings.
986      * @param sharedUserSetting The {@code SharedUserSetting} to adjust
987      * @param scannedPackage the package being scanned or null
988      * @param adjustedAbi the adjusted ABI calculated by {@link PackageAbiHelper}
989      * @return the list of code paths that belong to packages that had their ABIs adjusted.
990      */
applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting, ParsedPackage scannedPackage, String adjustedAbi)991     public static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting,
992             ParsedPackage scannedPackage, String adjustedAbi) {
993         if (scannedPackage != null)  {
994             scannedPackage.setPrimaryCpuAbi(adjustedAbi);
995         }
996         List<String> changedAbiCodePath = null;
997         final WatchedArraySet<PackageSetting> sharedUserPackageSettings =
998                 sharedUserSetting.getPackageSettings();
999         for (int i = 0; i < sharedUserPackageSettings.size(); i++) {
1000             PackageSetting ps = sharedUserPackageSettings.valueAt(i);
1001             if (scannedPackage == null
1002                     || !scannedPackage.getPackageName().equals(ps.getPackageName())) {
1003                 if (ps.getPrimaryCpuAbiLegacy() != null) {
1004                     continue;
1005                 }
1006 
1007                 ps.setPrimaryCpuAbi(adjustedAbi);
1008                 ps.onChanged();
1009                 if (ps.getPkg() != null) {
1010                     if (!TextUtils.equals(adjustedAbi,
1011                             AndroidPackageUtils.getRawPrimaryCpuAbi(ps.getPkg()))) {
1012                         if (DEBUG_ABI_SELECTION) {
1013                             Slog.i(TAG,
1014                                     "Adjusting ABI for " + ps.getPackageName() + " to "
1015                                             + adjustedAbi + " (scannedPackage="
1016                                             + (scannedPackage != null ? scannedPackage : "null")
1017                                             + ")");
1018                         }
1019                         if (changedAbiCodePath == null) {
1020                             changedAbiCodePath = new ArrayList<>();
1021                         }
1022                         changedAbiCodePath.add(ps.getPathString());
1023                     }
1024                 }
1025             }
1026         }
1027         return changedAbiCodePath;
1028     }
1029 
collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage, Settings.VersionInfo settingsVersionForPackage, boolean forceCollect, boolean skipVerify, boolean isPreNMR1Upgrade)1030     public static void collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage,
1031             Settings.VersionInfo settingsVersionForPackage, boolean forceCollect,
1032             boolean skipVerify, boolean isPreNMR1Upgrade)
1033             throws PackageManagerException {
1034         // When upgrading from pre-N MR1, verify the package time stamp using the package
1035         // directory and not the APK file.
1036         final long lastModifiedTime = isPreNMR1Upgrade
1037                 ? new File(parsedPackage.getPath()).lastModified()
1038                 : getLastModifiedTime(parsedPackage);
1039         if (ps != null && !forceCollect
1040                 && ps.getPathString().equals(parsedPackage.getPath())
1041                 && ps.getLastModifiedTime() == lastModifiedTime
1042                 && !ReconcilePackageUtils.isCompatSignatureUpdateNeeded(settingsVersionForPackage)
1043                 && !ReconcilePackageUtils.isRecoverSignatureUpdateNeeded(
1044                 settingsVersionForPackage)) {
1045             if (ps.getSigningDetails().getSignatures() != null
1046                     && ps.getSigningDetails().getSignatures().length != 0
1047                     && ps.getSigningDetails().getSignatureSchemeVersion()
1048                     != SigningDetails.SignatureSchemeVersion.UNKNOWN) {
1049                 // Optimization: reuse the existing cached signing data
1050                 // if the package appears to be unchanged.
1051                 parsedPackage.setSigningDetails(
1052                         new SigningDetails(ps.getSigningDetails()));
1053                 return;
1054             }
1055 
1056             Slog.w(TAG, "PackageSetting for " + ps.getPackageName()
1057                     + " is missing signatures.  Collecting certs again to recover them.");
1058         } else {
1059             Slog.i(TAG, parsedPackage.getPath() + " changed; collecting certs"
1060                     + (forceCollect ? " (forced)" : ""));
1061         }
1062 
1063         try {
1064             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
1065             final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
1066             final ParseResult<SigningDetails> result = ParsingPackageUtils.getSigningDetails(
1067                     input, parsedPackage, skipVerify);
1068             if (result.isError()) {
1069                 throw new PackageManagerException(
1070                         result.getErrorCode(), result.getErrorMessage(), result.getException());
1071             }
1072             parsedPackage.setSigningDetails(result.getResult());
1073         } finally {
1074             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1075         }
1076     }
1077 
setInstantAppForUser(PackageManagerServiceInjector injector, PackageSetting pkgSetting, int userId, boolean instantApp, boolean fullApp)1078     public static void setInstantAppForUser(PackageManagerServiceInjector injector,
1079             PackageSetting pkgSetting, int userId, boolean instantApp, boolean fullApp) {
1080         // no state specified; do nothing
1081         if (!instantApp && !fullApp) {
1082             return;
1083         }
1084         if (userId != UserHandle.USER_ALL) {
1085             if (instantApp && !pkgSetting.getInstantApp(userId)) {
1086                 pkgSetting.setInstantApp(true /*instantApp*/, userId);
1087             } else if (fullApp && pkgSetting.getInstantApp(userId)) {
1088                 pkgSetting.setInstantApp(false /*instantApp*/, userId);
1089             }
1090         } else {
1091             for (int currentUserId : injector.getUserManagerInternal().getUserIds()) {
1092                 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
1093                     pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
1094                 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
1095                     pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
1096                 }
1097             }
1098         }
1099     }
1100 
1101     /** Directory where installed application's 32-bit native libraries are copied. */
getAppLib32InstallDir()1102     public static File getAppLib32InstallDir() {
1103         return new File(Environment.getDataDirectory(), "app-lib");
1104     }
1105 }
1106