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