From eb403e7d372fc3cd7c1da4f6f8e24b681d96c451 Mon Sep 17 00:00:00 2001 From: Winson Date: Mon, 7 Feb 2022 11:41:08 -0800 Subject: [PATCH] Isolate IPackageManager implementation To avoid leaking IPackageManager methods directly into PackageManagerService, moves the IPM implementation into an inner class similar to PackageManagerInternal. This will help enforce snapshot consistency by ensuring that all non-IPM PMS methods can always take in a Computer instance to re-use. Bug: 217961172 Test: presubmit Change-Id: Ibf7bd3d1d90a40786279763ba8d62eb9348bb760 --- .../android/content/pm/IPackageManager.aidl | 11 - .../content/pm/PackageManagerInternal.java | 11 + .../server/pm/BackgroundDexOptService.java | 2 +- .../java/com/android/server/pm/Computer.java | 15 + .../server/pm/DeletePackageHelper.java | 35 +- .../com/android/server/pm/DexOptHelper.java | 3 +- .../com/android/server/pm/DumpHelper.java | 25 +- .../server/pm/DynamicCodeLoggingService.java | 6 +- .../server/pm/InstallPackageHelper.java | 3 +- .../com/android/server/pm/InstallParams.java | 4 +- .../server/pm/LauncherAppsService.java | 8 +- .../server/pm/PackageInstallerService.java | 8 +- .../server/pm/PackageInstallerSession.java | 33 +- .../server/pm/PackageManagerNative.java | 25 +- .../server/pm/PackageManagerService.java | 5172 +++++++++-------- .../server/pm/PackageManagerShellCommand.java | 4 +- .../server/pm/PreferredActivityHelper.java | 3 +- .../android/server/pm/UserManagerService.java | 3 +- .../android/server/pm/VerificationParams.java | 9 +- .../android/server/power/ShutdownThread.java | 4 +- .../storage/DeviceStorageMonitorService.java | 15 +- .../java/com/android/server/SystemServer.java | 12 +- ...geManagerComponentLabelIconOverrideTest.kt | 22 +- .../android/server/pm/PackageFreezerTest.kt | 18 +- .../PackageManagerServiceHibernationTests.kt | 5 +- .../pm/PackageInstallerSessionTest.java | 9 + .../wm/ActivityStartInterceptorTest.java | 10 +- 27 files changed, 2817 insertions(+), 2658 deletions(-) diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index e9e6cd3a54c5a..0f236dfe1a8bf 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -497,20 +497,9 @@ interface IPackageManager { void enterSafeMode(); @UnsupportedAppUsage boolean isSafeMode(); - void systemReady(); @UnsupportedAppUsage boolean hasSystemUidErrors(); - /** - * Ask the package manager to fstrim the disk if needed. - */ - void performFstrimIfNeeded(); - - /** - * Ask the package manager to update packages if needed. - */ - void updatePackagesIfNeeded(); - /** * Notify the package manager that a package is going to be used and why. * diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index c9d704084c194..2068e6d380b7c 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -45,6 +45,7 @@ import android.util.SparseArray; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.pm.PackageList; import com.android.server.pm.PackageSetting; +import com.android.server.pm.dex.DynamicCodeLogger; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.pkg.AndroidPackageApi; import com.android.server.pm.pkg.PackageState; @@ -68,6 +69,7 @@ import java.util.function.Consumer; * @hide Only for use within the system server. */ public abstract class PackageManagerInternal { + @IntDef(prefix = "PACKAGE_", value = { PACKAGE_SYSTEM, PACKAGE_SETUP_WIZARD, @@ -902,6 +904,11 @@ public abstract class PackageManagerInternal { public abstract void freeStorage(String volumeUuid, long bytes, @StorageManager.AllocateFlags int flags) throws IOException; + /** + * Blocking call to clear all cached app data above quota. + */ + public abstract void freeAllAppCacheAboveQuota(@NonNull String volumeUuid) throws IOException; + /** Returns {@code true} if the specified component is enabled and matches the given flags. */ public abstract boolean isEnabledAndMatches(@NonNull ParsedMainComponent component, @PackageManager.ComponentInfoFlagsBits long flags, int userId); @@ -1362,4 +1369,8 @@ public abstract class PackageManagerInternal { */ @NonNull public abstract PackageDataSnapshot snapshot(); + + public abstract void shutdown(); + + public abstract DynamicCodeLogger getDynamicCodeLogger(); } diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index 31df0a53eaa9d..ecbb4a9d45a10 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -557,7 +557,7 @@ public final class BackgroundDexOptService { /** Gets the size of a package. */ private long getPackageSize(PackageManagerService pm, String pkg) { - PackageInfo info = pm.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); + PackageInfo info = pm.snapshotComputer().getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); long size = 0; if (info != null && info.applicationInfo != null) { File path = Paths.get(info.applicationInfo.sourceDir).toFile(); diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java index 2a4882ac7d4f0..6103d688e2b1d 100644 --- a/services/core/java/com/android/server/pm/Computer.java +++ b/services/core/java/com/android/server/pm/Computer.java @@ -284,6 +284,21 @@ public interface Computer extends PackageDataSnapshot { @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED) long updateFlagsForResolve(long flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc); + + /** + * Checks if the request is from the system or an app that has the appropriate cross-user + * permissions defined as follows: + * + * + * @param checkShell whether to prevent shell from access if there's a debugging restriction + * @param message the message to log on security exception + */ @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED) void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message); diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java index 87a83effee1ae..a9dc0f3854f0a 100644 --- a/services/core/java/com/android/server/pm/DeletePackageHelper.java +++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java @@ -685,7 +685,8 @@ final class DeletePackageHelper { return; } - if (!deleteAllUsers && mPm.getBlockUninstallForUser(internalPackageName, userId)) { + if (!deleteAllUsers && mPm.mIPackageManager + .getBlockUninstallForUser(internalPackageName, userId)) { mPm.mHandler.post(() -> { try { observer.onPackageDeleted(packageName, @@ -705,11 +706,14 @@ final class DeletePackageHelper { // Queue up an async operation since the package deletion may take a little while. mPm.mHandler.post(() -> { int returnCode; - final PackageSetting ps = mPm.mSettings.getPackageLPr(internalPackageName); + final Computer innerSnapshot = mPm.snapshotComputer(); + final PackageStateInternal packageState = + innerSnapshot.getPackageStateInternal(internalPackageName); boolean doDeletePackage = true; - if (ps != null) { + if (packageState != null) { final boolean targetIsInstantApp = - ps.getInstantApp(UserHandle.getUserId(callingUid)); + packageState.getUserStateOrDefault(UserHandle.getUserId(callingUid)) + .isInstantApp(); doDeletePackage = !targetIsInstantApp || canViewInstantApps; } @@ -718,7 +722,7 @@ final class DeletePackageHelper { returnCode = deletePackageX(internalPackageName, versionCode, userId, deleteFlags, false /*removedBySystem*/); } else { - int[] blockUninstallUserIds = getBlockUninstallForUsers( + int[] blockUninstallUserIds = getBlockUninstallForUsers(innerSnapshot, internalPackageName, users); // If nobody is blocking uninstall, proceed with delete for all users if (ArrayUtils.isEmpty(blockUninstallUserIds)) { @@ -769,39 +773,40 @@ final class DeletePackageHelper { } final int callingUserId = UserHandle.getUserId(callingUid); // If the caller installed the pkgName, then allow it to silently uninstall. - if (callingUid == mPm.getPackageUid( - mPm.getInstallerPackageName(pkgName), 0, callingUserId)) { + if (callingUid == mPm.mIPackageManager.getPackageUid( + mPm.mIPackageManager.getInstallerPackageName(pkgName), 0, callingUserId)) { return true; } // Allow package verifier to silently uninstall. - if (mPm.mRequiredVerifierPackage != null && callingUid == mPm.getPackageUid( - mPm.mRequiredVerifierPackage, 0, callingUserId)) { + if (mPm.mRequiredVerifierPackage != null && callingUid == mPm.mIPackageManager + .getPackageUid(mPm.mRequiredVerifierPackage, 0, callingUserId)) { return true; } // Allow package uninstaller to silently uninstall. - if (mPm.mRequiredUninstallerPackage != null && callingUid == mPm.getPackageUid( - mPm.mRequiredUninstallerPackage, 0, callingUserId)) { + if (mPm.mRequiredUninstallerPackage != null && callingUid == mPm.mIPackageManager + .getPackageUid(mPm.mRequiredUninstallerPackage, 0, callingUserId)) { return true; } // Allow storage manager to silently uninstall. - if (mPm.mStorageManagerPackage != null && callingUid == mPm.getPackageUid( + if (mPm.mStorageManagerPackage != null && callingUid == mPm.mIPackageManager.getPackageUid( mPm.mStorageManagerPackage, 0, callingUserId)) { return true; } // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently // uninstall for device owner provisioning. - return mPm.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid) + return mPm.mIPackageManager.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid) == PERMISSION_GRANTED; } - private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { + private int[] getBlockUninstallForUsers(@NonNull Computer snapshot, String packageName, + int[] userIds) { int[] result = EMPTY_INT_ARRAY; for (int userId : userIds) { - if (mPm.getBlockUninstallForUser(packageName, userId)) { + if (snapshot.getBlockUninstallForUser(packageName, userId)) { result = ArrayUtils.appendInt(result, userId); } } diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java index c8326931f6fd4..74ea7cc9b4e14 100644 --- a/services/core/java/com/android/server/pm/DexOptHelper.java +++ b/services/core/java/com/android/server/pm/DexOptHelper.java @@ -304,7 +304,8 @@ final class DexOptHelper { /*package*/ boolean performDexOpt(DexoptOptions options) { if (mPm.getInstantAppPackageName(Binder.getCallingUid()) != null) { return false; - } else if (mPm.isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) { + } else if (mPm.mIPackageManager.isInstantApp(options.getPackageName(), + UserHandle.getCallingUserId())) { return false; } diff --git a/services/core/java/com/android/server/pm/DumpHelper.java b/services/core/java/com/android/server/pm/DumpHelper.java index 2b46ed4049450..05ef3c4ec300e 100644 --- a/services/core/java/com/android/server/pm/DumpHelper.java +++ b/services/core/java/com/android/server/pm/DumpHelper.java @@ -288,6 +288,8 @@ final class DumpHelper { ipw.decreaseIndent(); } + final Computer snapshot = mPm.snapshotComputer(); + if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { final String requiredVerifierPackage = mPm.mRequiredVerifierPackage; @@ -299,14 +301,14 @@ final class DumpHelper { pw.print(" Required: "); pw.print(requiredVerifierPackage); pw.print(" (uid="); - pw.print(mPm.getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, - UserHandle.USER_SYSTEM)); + pw.print(snapshot.getPackageUid(requiredVerifierPackage, + MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM)); pw.println(")"); } else if (requiredVerifierPackage != null) { pw.print("vrfy,"); pw.print(requiredVerifierPackage); pw.print(","); - pw.println(mPm.getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, - UserHandle.USER_SYSTEM)); + pw.println(snapshot.getPackageUid(requiredVerifierPackage, + MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM)); } } @@ -324,14 +326,14 @@ final class DumpHelper { pw.print(" Using: "); pw.print(verifierPackageName); pw.print(" (uid="); - pw.print(mPm.getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, - UserHandle.USER_SYSTEM)); + pw.print(snapshot.getPackageUid(verifierPackageName, + MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM)); pw.println(")"); } else if (verifierPackageName != null) { pw.print("dv,"); pw.print(verifierPackageName); pw.print(","); - pw.println(mPm.getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, - UserHandle.USER_SYSTEM)); + pw.println(snapshot.getPackageUid(verifierPackageName, + MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM)); } } else { pw.println(); @@ -405,7 +407,7 @@ final class DumpHelper { } if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { - mPm.mComponentResolver.dumpContentProviders(mPm.snapshotComputer(), pw, dumpState, + mPm.mComponentResolver.dumpContentProviders(snapshot, pw, dumpState, packageName); } @@ -661,13 +663,14 @@ final class DumpHelper { final ProtoOutputStream proto = new ProtoOutputStream(fd); synchronized (mPm.mLock) { + final Computer snapshot = mPm.snapshotComputer(); final long requiredVerifierPackageToken = proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE); proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mPm.mRequiredVerifierPackage); proto.write( PackageServiceDumpProto.PackageShortProto.UID, - mPm.getPackageUid( + snapshot.getPackageUid( mPm.mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM)); @@ -682,7 +685,7 @@ final class DumpHelper { proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName); proto.write( PackageServiceDumpProto.PackageShortProto.UID, - mPm.getPackageUid( + snapshot.getPackageUid( verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM)); diff --git a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java index c65c2b1127069..b4bcd5b3308c9 100644 --- a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java +++ b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java @@ -22,11 +22,12 @@ import android.app.job.JobScheduler; import android.app.job.JobService; import android.content.ComponentName; import android.content.Context; +import android.content.pm.PackageManagerInternal; import android.os.Process; -import android.os.ServiceManager; import android.util.EventLog; import android.util.Log; +import com.android.server.LocalServices; import com.android.server.pm.dex.DynamicCodeLogger; import libcore.util.HexEncoding; @@ -133,8 +134,7 @@ public class DynamicCodeLoggingService extends JobService { } private static DynamicCodeLogger getDynamicCodeLogger() { - PackageManagerService pm = (PackageManagerService) ServiceManager.getService("package"); - return pm.getDexManager().getDynamicCodeLogger(); + return LocalServices.getService(PackageManagerInternal.class).getDynamicCodeLogger(); } private class IdleLoggingThread extends Thread { diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 6e4d19f8d277d..b5d63f3bb4c02 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -2867,13 +2867,14 @@ final class InstallPackageHelper { VMRuntime.getRuntime().requestConcurrentGC(); } + final Computer snapshot = mPm.snapshotComputer(); // Notify DexManager that the package was installed for new users. // The updated users should already be indexed and the package code paths // should not change. // Don't notify the manager for ephemeral apps as they are not expected to // survive long enough to benefit of background optimizations. for (int userId : firstUserIds) { - PackageInfo info = mPm.getPackageInfo(packageName, /*flags*/ 0, userId); + PackageInfo info = snapshot.getPackageInfo(packageName, /*flags*/ 0, userId); // There's a race currently where some install events may interleave with an // uninstall. This can lead to package info being null (b/36642664). if (info != null) { diff --git a/services/core/java/com/android/server/pm/InstallParams.java b/services/core/java/com/android/server/pm/InstallParams.java index 6c80976c0f78b..18d2b0c23320f 100644 --- a/services/core/java/com/android/server/pm/InstallParams.java +++ b/services/core/java/com/android/server/pm/InstallParams.java @@ -289,8 +289,8 @@ final class InstallParams extends HandlerParams { */ private int fixUpInstallReason(String installerPackageName, int installerUid, int installReason) { - if (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid) - == PERMISSION_GRANTED) { + if (mPm.snapshotComputer().checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, + installerUid) == PERMISSION_GRANTED) { // If the install is being performed by a system app, we trust that app to have set the // install reason correctly. return installReason; diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index e9896617d8e8d..5e0fc3bf91e7a 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -320,8 +320,12 @@ public class LauncherAppsService extends SystemService { private PackageInstallerService getPackageInstallerService() { if (mPackageInstallerService == null) { - mPackageInstallerService = ((PackageInstallerService) ((PackageManagerService) - ServiceManager.getService("package")).getPackageInstaller()); + try { + mPackageInstallerService = ((PackageInstallerService) ((IPackageManager) + ServiceManager.getService("package")).getPackageInstaller()); + } catch (RemoteException e) { + Slog.wtf(TAG, "Error gettig IPackageInstaller", e); + } } return mPackageInstallerService; } diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index fe2fe097bdf6c..0a193573f7016 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -676,7 +676,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements String originatingPackageName = null; if (params.originatingUid != SessionParams.UID_UNKNOWN && params.originatingUid != callingUid) { - String[] packages = mPm.getPackagesForUid(params.originatingUid); + String[] packages = mPm.mIPackageManager.getPackagesForUid(params.originatingUid); if (packages != null && packages.length > 0) { // Choose an arbitrary representative package in the case of a shared UID. originatingPackageName = packages[0]; @@ -727,7 +727,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements if ((params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0 && !isCalledBySystemOrShell(callingUid) - && (mPm.getFlagsForUid(callingUid) & ApplicationInfo.FLAG_SYSTEM) == 0) { + && (mPm.mIPackageManager.getFlagsForUid(callingUid) & ApplicationInfo.FLAG_SYSTEM) + == 0) { throw new SecurityException( "Only system apps could use the PackageManager.INSTALL_INSTANT_APP flag."); } @@ -1153,7 +1154,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements .setAdmin(callerPackageName) .write(); } else { - ApplicationInfo appInfo = mPm.getApplicationInfo(callerPackageName, 0, userId); + ApplicationInfo appInfo = mPm.mIPackageManager + .getApplicationInfo(callerPackageName, 0, userId); if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P) { mContext.enforceCallingOrSelfPermission(Manifest.permission.REQUEST_DELETE_PACKAGES, null); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 67d3f9588e3b3..ef7158a80a546 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -817,25 +817,26 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } // It is safe to access mInstallerUid and mInstallSource without lock // because they are immutable after sealing. + final Computer snapshot = mPm.snapshotComputer(); final boolean isInstallPermissionGranted = - (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, + (snapshot.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, mInstallerUid) == PackageManager.PERMISSION_GRANTED); final boolean isSelfUpdatePermissionGranted = - (mPm.checkUidPermission(android.Manifest.permission.INSTALL_SELF_UPDATES, + (snapshot.checkUidPermission(android.Manifest.permission.INSTALL_SELF_UPDATES, mInstallerUid) == PackageManager.PERMISSION_GRANTED); final boolean isUpdatePermissionGranted = - (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGE_UPDATES, + (snapshot.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGE_UPDATES, mInstallerUid) == PackageManager.PERMISSION_GRANTED); - final boolean isUpdateWithoutUserActionPermissionGranted = (mPm.checkUidPermission( + final boolean isUpdateWithoutUserActionPermissionGranted = (snapshot.checkUidPermission( android.Manifest.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION, mInstallerUid) == PackageManager.PERMISSION_GRANTED); - final boolean isInstallDpcPackagesPermissionGranted = (mPm.checkUidPermission( + final boolean isInstallDpcPackagesPermissionGranted = (snapshot.checkUidPermission( android.Manifest.permission.INSTALL_DPC_PACKAGES, mInstallerUid) == PackageManager.PERMISSION_GRANTED); - final int targetPackageUid = mPm.getPackageUid(packageName, 0, userId); + final int targetPackageUid = snapshot.getPackageUid(packageName, 0, userId); final boolean isUpdate = targetPackageUid != -1 || isApexSession(); final InstallSourceInfo existingInstallSourceInfo = isUpdate - ? mPm.getInstallSourceInfo(packageName) + ? snapshot.getInstallSourceInfo(packageName) : null; final String existingInstallerPackageName = existingInstallSourceInfo != null ? existingInstallSourceInfo.getInstallingPackageName() @@ -2009,12 +2010,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void transfer(String packageName) { Preconditions.checkArgument(!TextUtils.isEmpty(packageName)); - ApplicationInfo newOwnerAppInfo = mPm.getApplicationInfo(packageName, 0, userId); + final Computer snapshot = mPm.snapshotComputer(); + ApplicationInfo newOwnerAppInfo = snapshot.getApplicationInfo(packageName, 0, userId); if (newOwnerAppInfo == null) { throw new ParcelableException(new PackageManager.NameNotFoundException(packageName)); } - if (PackageManager.PERMISSION_GRANTED != mPm.checkUidPermission( + if (PackageManager.PERMISSION_GRANTED != snapshot.checkUidPermission( Manifest.permission.INSTALL_PACKAGES, newOwnerAppInfo.uid)) { throw new SecurityException("Destination package " + packageName + " does not have " + "the " + Manifest.permission.INSTALL_PACKAGES + " permission"); @@ -2509,7 +2511,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Package didn't install; no valid uid packageUid = Process.INVALID_UID; } else { - packageUid = mPm.getPackageUid(packageName, 0, userId); + packageUid = mPm.snapshotComputer().getPackageUid(packageName, 0, userId); } FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_INSTALLER_V2_REPORTED, isIncrementalInstallation(), @@ -2667,7 +2669,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mResolvedStagedFiles.clear(); mResolvedInheritedFiles.clear(); - final PackageInfo pkgInfo = mPm.getPackageInfo( + final PackageInfo pkgInfo = mPm.snapshotComputer().getPackageInfo( params.appPackageName, PackageManager.GET_SIGNATURES | PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES /*flags*/, userId); @@ -3786,8 +3788,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { }; try { - final PackageInfo pkgInfo = mPm.getPackageInfo(this.params.appPackageName, 0, - userId); + final PackageInfo pkgInfo = mPm.snapshotComputer() + .getPackageInfo(this.params.appPackageName, 0, userId); final File inheritedDir = (pkgInfo != null && pkgInfo.applicationInfo != null) ? new File( pkgInfo.applicationInfo.getCodePath()).getParentFile() : null; @@ -4532,8 +4534,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final String installerPackageName = readStringAttribute(in, ATTR_INSTALLER_PACKAGE_NAME); final String installerAttributionTag = readStringAttribute(in, ATTR_INSTALLER_ATTRIBUTION_TAG); - final int installerUid = in.getAttributeInt(null, ATTR_INSTALLER_UID, pm.getPackageUid( - installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId)); + final int installerUid = in.getAttributeInt(null, ATTR_INSTALLER_UID, pm.snapshotComputer() + .getPackageUid(installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, + userId)); final String installInitiatingPackageName = readStringAttribute(in, ATTR_INITIATING_PACKAGE_NAME); final String installOriginatingPackageName = diff --git a/services/core/java/com/android/server/pm/PackageManagerNative.java b/services/core/java/com/android/server/pm/PackageManagerNative.java index 37daf112aa69c..9a43008acfdfd 100644 --- a/services/core/java/com/android/server/pm/PackageManagerNative.java +++ b/services/core/java/com/android/server/pm/PackageManagerNative.java @@ -71,7 +71,7 @@ final class PackageManagerNative extends IPackageManagerNative.Stub { @Override public String[] getAllPackages() { - return mPm.getAllPackages().toArray(new String[0]); + return mPm.snapshotComputer().getAllPackages().toArray(new String[0]); } @Override @@ -82,7 +82,7 @@ final class PackageManagerNative extends IPackageManagerNative.Stub { if (uids == null || uids.length == 0) { return null; } - names = mPm.getNamesForUids(uids); + names = mPm.snapshotComputer().getNamesForUids(uids); results = (names != null) ? names : new String[uids.length]; // massage results so they can be parsed by the native binder for (int i = results.length - 1; i >= 0; --i) { @@ -104,13 +104,14 @@ final class PackageManagerNative extends IPackageManagerNative.Stub { // NB: this differentiates between preloads and sideloads @Override public String getInstallerForPackage(String packageName) throws RemoteException { - final String installerName = mPm.getInstallerPackageName(packageName); + final Computer snapshot = mPm.snapshotComputer(); + final String installerName = snapshot.getInstallerPackageName(packageName); if (!TextUtils.isEmpty(installerName)) { return installerName; } // differentiate between preload and sideload int callingUser = UserHandle.getUserId(Binder.getCallingUid()); - ApplicationInfo appInfo = mPm.getApplicationInfo(packageName, + ApplicationInfo appInfo = snapshot.getApplicationInfo(packageName, /*flags*/ 0, /*userId*/ callingUser); if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { @@ -123,7 +124,8 @@ final class PackageManagerNative extends IPackageManagerNative.Stub { public long getVersionCodeForPackage(String packageName) throws RemoteException { try { int callingUser = UserHandle.getUserId(Binder.getCallingUid()); - PackageInfo pInfo = mPm.getPackageInfo(packageName, 0, callingUser); + PackageInfo pInfo = mPm.snapshotComputer() + .getPackageInfo(packageName, 0, callingUser); if (pInfo != null) { return pInfo.getLongVersionCode(); } @@ -134,7 +136,7 @@ final class PackageManagerNative extends IPackageManagerNative.Stub { @Override public int getTargetSdkVersionForPackage(String packageName) throws RemoteException { - int targetSdk = mPm.getTargetSdkVersion(packageName); + int targetSdk = mPm.snapshotComputer().getTargetSdkVersion(packageName); if (targetSdk != -1) { return targetSdk; } @@ -145,7 +147,8 @@ final class PackageManagerNative extends IPackageManagerNative.Stub { @Override public boolean isPackageDebuggable(String packageName) throws RemoteException { int callingUser = UserHandle.getCallingUserId(); - ApplicationInfo appInfo = mPm.getApplicationInfo(packageName, 0, callingUser); + ApplicationInfo appInfo = mPm.snapshotComputer() + .getApplicationInfo(packageName, 0, callingUser); if (appInfo != null) { return (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE)); } @@ -157,9 +160,10 @@ final class PackageManagerNative extends IPackageManagerNative.Stub { public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames) throws RemoteException { int callingUser = UserHandle.getUserId(Binder.getCallingUid()); + final Computer snapshot = mPm.snapshotComputer(); boolean[] results = new boolean[packageNames.length]; for (int i = results.length - 1; i >= 0; --i) { - ApplicationInfo appInfo = mPm.getApplicationInfo(packageNames[i], 0, callingUser); + ApplicationInfo appInfo = snapshot.getApplicationInfo(packageNames[i], 0, callingUser); results[i] = appInfo != null && appInfo.isAudioPlaybackCaptureAllowed(); } return results; @@ -168,7 +172,7 @@ final class PackageManagerNative extends IPackageManagerNative.Stub { @Override public int getLocationFlags(String packageName) throws RemoteException { int callingUser = UserHandle.getUserId(Binder.getCallingUid()); - ApplicationInfo appInfo = mPm.getApplicationInfo(packageName, + ApplicationInfo appInfo = mPm.snapshotComputer().getApplicationInfo(packageName, /*flags*/ 0, /*userId*/ callingUser); if (appInfo == null) { @@ -188,7 +192,8 @@ final class PackageManagerNative extends IPackageManagerNative.Stub { @Override public boolean hasSha256SigningCertificate(String packageName, byte[] certificate) throws RemoteException { - return mPm.hasSigningCertificate(packageName, certificate, CERT_INPUT_SHA256); + return mPm.snapshotComputer() + .hasSigningCertificate(packageName, certificate, CERT_INPUT_SHA256); } @Override diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index a70cff98ed936..e20a861e2eae4 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -105,11 +105,6 @@ import android.content.pm.PackageInfoLite; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.PackageManager.ComponentEnabledSetting; -import android.content.pm.PackageManager.ComponentType; -import android.content.pm.PackageManager.LegacyPackageDeleteObserver; -import android.content.pm.PackageManager.ModuleInfoFlags; -import android.content.pm.PackageManager.Property; -import android.content.pm.PackageManager.PropertyLocation; import android.content.pm.PackageManagerInternal; import android.content.pm.PackagePartitions; import android.content.pm.ParceledListSlice; @@ -218,6 +213,7 @@ import com.android.server.pm.Settings.VersionInfo; import com.android.server.pm.dex.ArtManagerService; import com.android.server.pm.dex.ArtUtils; import com.android.server.pm.dex.DexManager; +import com.android.server.pm.dex.DynamicCodeLogger; import com.android.server.pm.dex.ViewCompiler; import com.android.server.pm.parsing.PackageCacher; import com.android.server.pm.parsing.PackageInfoUtils; @@ -334,8 +330,8 @@ import java.util.function.Consumer; * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases * */ -public class PackageManagerService extends IPackageManager.Stub - implements PackageSender, TestUtilityService { +public class PackageManagerService implements PackageSender, TestUtilityService { + static final String TAG = "PackageManager"; public static final boolean DEBUG_SETTINGS = false; static final boolean DEBUG_PREFERRED = false; @@ -648,6 +644,8 @@ public class PackageManagerService extends IPackageManager.Stub */ boolean mPromoteSystemApps; + // TODO: Make IPackageManager reference private to hide discouraged APIs + final IPackageManagerImpl mIPackageManager; private final PackageManagerInternal mPmInternal; private final TestUtilityService mTestUtilityService; @@ -1060,7 +1058,7 @@ public class PackageManagerService extends IPackageManager.Stub private volatile Computer mSnapshotComputer; // A trampoline that directs callers to either the live or snapshot computer. - private final ComputerTracker mComputer = new ComputerTracker(this); + final ComputerTracker mComputer = new ComputerTracker(this); // If true, the snapshot is invalid (stale). The attribute is static since it may be // set from outside classes. The attribute may be set to true anywhere, although it @@ -1168,15 +1166,6 @@ public class PackageManagerService extends IPackageManager.Stub onChange(null); } - @Override - public void notifyPackagesReplacedReceived(String[] packages) { - Computer computer = snapshotComputer(); - ArraySet packagesToNotify = computer.getNotifyPackagesForReplacedReceived(packages); - for (int index = 0; index < packagesToNotify.size(); index++) { - notifyInstallObserver(packagesToNotify.valueAt(index), false /* killApp */); - } - } - void notifyInstallObserver(String packageName, boolean killApp) { final Pair pair = killApp ? mPendingKillInstallObservers.remove(packageName) @@ -1233,16 +1222,6 @@ public class PackageManagerService extends IPackageManager.Stub PRUNE_UNUSED_SHARED_LIBRARIES_DELAY); } - @Override - public void requestPackageChecksums(@NonNull String packageName, boolean includeSplits, - @Checksum.TypeMask int optional, @Checksum.TypeMask int required, - @Nullable List trustedInstallers, - @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId) { - requestChecksumsInternal(packageName, includeSplits, optional, required, trustedInstallers, - onChecksumsReadyListener, userId, mInjector.getBackgroundExecutor(), - mInjector.getBackgroundHandler()); - } - /** * Requests checksums for the APK file. * See {@link PackageInstaller.Session#requestChecksums} for details. @@ -1290,7 +1269,8 @@ public class PackageManagerService extends IPackageManager.Stub if (applicationInfo == null) { throw new ParcelableException(new PackageManager.NameNotFoundException(packageName)); } - final InstallSourceInfo installSourceInfo = getInstallSourceInfo(packageName); + final InstallSourceInfo installSourceInfo = + mIPackageManager.getInstallSourceInfo(packageName); final String installerPackageName = installSourceInfo != null ? installSourceInfo.getInitiatingPackageName() : null; @@ -1432,9 +1412,9 @@ public class PackageManagerService extends IPackageManager.Stub } } - public static PackageManagerService main(Context context, Installer installer, - @NonNull DomainVerificationService domainVerificationService, boolean factoryTest, - boolean onlyCore) { + public static Pair main(Context context, + Installer installer, @NonNull DomainVerificationService domainVerificationService, + boolean factoryTest, boolean onlyCore) { // Self-check for initial settings. PackageManagerServiceCompilerMapping.checkProperties(); final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing", @@ -1465,10 +1445,10 @@ public class PackageManagerService extends IPackageManager.Stub (i, pm) -> SystemConfig.getInstance(), (i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(), i.getContext(), "*dexopt*"), - (i, pm) -> new DexManager(i.getContext(), pm, i.getPackageDexOptimizer(), + (i, pm) -> new DexManager(i.getContext(), pm.mIPackageManager, + i.getPackageDexOptimizer(), i.getInstaller(), i.getInstallLock()), + (i, pm) -> new ArtManagerService(i.getContext(), pm.mIPackageManager, i.getInstaller(), i.getInstallLock()), - (i, pm) -> new ArtManagerService(i.getContext(), pm, i.getInstaller(), - i.getInstallLock()), (i, pm) -> ApexManager.getInstance(), (i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()), (i, pm) -> (IncrementalManager) @@ -1490,7 +1470,7 @@ public class PackageManagerService extends IPackageManager.Stub i.getContext(), pm, i::getScanningPackageParser), (i, pm, cn) -> new InstantAppResolverConnection( i.getContext(), cn, Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE), - (i, pm) -> new ModuleInfoProvider(i.getContext(), pm), + (i, pm) -> new ModuleInfoProvider(i.getContext(), pm.mIPackageManager), (i, pm) -> LegacyPermissionManagerService.create(i.getContext()), (i, pm) -> domainVerificationService, (i, pm) -> { @@ -1551,11 +1531,11 @@ public class PackageManagerService extends IPackageManager.Stub selinuxChangeListener); m.installAllowlistedSystemPackages(); - ServiceManager.addService("package", m); + ServiceManager.addService("package", m.mIPackageManager); final PackageManagerNative pmn = new PackageManagerNative(m); ServiceManager.addService("package_native", pmn); LocalManagerRegistry.addManager(PackageManagerLocal.class, m.new PackageManagerLocalImpl()); - return m; + return Pair.create(m, m.mIPackageManager); } /** Install/uninstall system packages for all users based on their user-type, as applicable. */ @@ -1661,6 +1641,7 @@ public class PackageManagerService extends IPackageManager.Stub mPackageDexOptimizer = testParams.packageDexOptimizer; mPackageParserCallback = testParams.packageParserCallback; mPendingBroadcasts = testParams.pendingPackageBroadcasts; + mIPackageManager = new IPackageManagerImpl(); mPmInternal = testParams.pmInternal; mTestUtilityService = testParams.testUtilityService; mProcessLoggingHandler = testParams.processLoggingHandler; @@ -1722,6 +1703,7 @@ public class PackageManagerService extends IPackageManager.Stub public PackageManagerService(PackageManagerServiceInjector injector, boolean onlyCore, boolean factoryTest, final String buildFingerprint, final boolean isEngBuild, final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) { + mIPackageManager = new IPackageManagerImpl(); mIsEngBuild = isEngBuild; mIsUserDebugBuild = isUserDebugBuild; mSdkVersion = sdkVersion; @@ -1773,7 +1755,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean hasFeature(String feature) { - return PackageManagerService.this.hasSystemFeature(feature, 0); + return PackageManagerService.this.mIPackageManager.hasSystemFeature(feature, 0); } }; @@ -2000,11 +1982,13 @@ public class PackageManagerService extends IPackageManager.Stub mSetupWizardPackage = getSetupWizardPackageNameImpl(computer); mComponentResolver.fixProtectedFilterPriorities(mPmInternal.getSetupWizardPackageName()); - mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName(); - mSystemTextClassifierPackageName = getSystemTextClassifierPackageName(); + mDefaultTextClassifierPackage = mIPackageManager.getDefaultTextClassifierPackageName(); + mSystemTextClassifierPackageName = + mIPackageManager.getSystemTextClassifierPackageName(); mConfiguratorPackage = getDeviceConfiguratorPackageName(); - mAppPredictionServicePackage = getAppPredictionServicePackageName(); - mIncidentReportApproverPackage = getIncidentReportApproverPackageName(); + mAppPredictionServicePackage = mIPackageManager.getAppPredictionServicePackageName(); + mIncidentReportApproverPackage = + mIPackageManager.getIncidentReportApproverPackageName(); mRetailDemoPackage = getRetailDemoPackageName(); mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName(); mRecentsPackage = getRecentsPackageName(); @@ -2159,7 +2143,7 @@ public class PackageManagerService extends IPackageManager.Stub mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr(computer); mSettings.setPermissionControllerVersion( - getPackageInfo(mRequiredPermissionControllerPackage, 0, + mIPackageManager.getPackageInfo(mRequiredPermissionControllerPackage, 0, UserHandle.USER_SYSTEM).getLongVersionCode()); // Resolve the sdk sandbox package @@ -2207,7 +2191,8 @@ public class PackageManagerService extends IPackageManager.Stub // scanning). final Map> userPackages = new HashMap<>(); for (int userId : userIds) { - userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList()); + userPackages.put(userId, mIPackageManager.getInstalledPackages(/*flags*/ 0, userId) + .getList()); } mDexManager.load(userPackages); if (mIsUpgrade) { @@ -2260,19 +2245,16 @@ public class PackageManagerService extends IPackageManager.Stub setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr()); } - @Override public boolean isFirstBoot() { // allow instant applications return mFirstBoot; } - @Override public boolean isOnlyCoreApps() { // allow instant applications return mOnlyCore; } - @Override public boolean isDeviceUpgrading() { // allow instant applications // The system property allows testing ota flow when upgraded to the same image. @@ -2393,8 +2375,9 @@ public class PackageManagerService extends IPackageManager.Stub for (int i = 0; i < N; i++) { final ResolveInfo cur = matches.get(i); final String packageName = cur.getComponentInfo().packageName; - if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, - packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { + if (mIPackageManager.checkPermission( + android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, packageName, + UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { continue; } @@ -2422,8 +2405,9 @@ public class PackageManagerService extends IPackageManager.Stub for (int i = 0; i < N; i++) { final ResolveInfo cur = matches.get(i); final String packageName = cur.getComponentInfo().packageName; - if (checkPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, - packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { + if (mIPackageManager.checkPermission( + android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, packageName, + UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { Slog.w(TAG, "Domain verification agent found but does not hold permission: " + packageName); continue; @@ -2446,14 +2430,6 @@ public class PackageManagerService extends IPackageManager.Stub return null; } - @Override - public @Nullable ComponentName getInstantAppResolverComponent() { - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { - return null; - } - return getInstantAppResolver(); - } - private @Nullable ComponentName getInstantAppResolver() { final String[] packageArray = mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); @@ -2543,7 +2519,7 @@ public class PackageManagerService extends IPackageManager.Stub Iterator iter = matches.iterator(); while (iter.hasNext()) { final ResolveInfo rInfo = iter.next(); - if (checkPermission( + if (mIPackageManager.checkPermission( Manifest.permission.INSTALL_PACKAGES, rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || mIsEngBuild) { continue; @@ -2574,18 +2550,18 @@ public class PackageManagerService extends IPackageManager.Stub return matches.get(0).getComponentInfo().getComponentName(); } - @Override - public boolean onTransact(int code, Parcel data, Parcel reply, int flags) - throws RemoteException { - try { - return super.onTransact(code, data, reply, flags); - } catch (RuntimeException e) { - if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException) - && !(e instanceof ParcelableException)) { - Slog.wtf(TAG, "Package Manager Unexpected Exception", e); - } - throw e; - } + /** + * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int) + */ + boolean shouldFilterApplication( + @Nullable PackageStateInternal ps, int callingUid, int userId) { + return mComputer.shouldFilterApplication( + ps, callingUid, userId); + } + + private @PackageStartability int getPackageStartability(String packageName, + int callingUid, int userId) { + return mComputer.getPackageStartability(mSafeMode, packageName, callingUid, userId); } /** @@ -2611,118 +2587,11 @@ public class PackageManagerService extends IPackageManager.Stub return mComputer.generatePackageInfo(ps, flags, userId); } - @Override - public void checkPackageStartable(String packageName, int userId) { - final int callingUid = Binder.getCallingUid(); - if (getInstantAppPackageName(callingUid) != null) { - throw new SecurityException("Instant applications don't have access to this method"); - } - if (!mUserManager.exists(userId)) { - throw new SecurityException("User doesn't exist"); - } - enforceCrossUserPermission(callingUid, userId, false, false, "checkPackageStartable"); - switch (getPackageStartability(packageName, callingUid, userId)) { - case PACKAGE_STARTABILITY_NOT_FOUND: - throw new SecurityException("Package " + packageName + " was not found!"); - case PACKAGE_STARTABILITY_NOT_SYSTEM: - throw new SecurityException("Package " + packageName + " not a system app!"); - case PACKAGE_STARTABILITY_FROZEN: - throw new SecurityException("Package " + packageName + " is currently frozen!"); - case PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED: - throw new SecurityException("Package " + packageName + " is not encryption aware!"); - case PACKAGE_STARTABILITY_OK: - default: - } - } - - private @PackageStartability int getPackageStartability(String packageName, - int callingUid, int userId) { - return mComputer.getPackageStartability(mSafeMode, packageName, callingUid, userId); - } - - @Override - public boolean isPackageAvailable(String packageName, int userId) { - return mComputer.isPackageAvailable(packageName, userId); - } - - @Override - public PackageInfo getPackageInfo(String packageName, - @PackageManager.PackageInfoFlagsBits long flags, int userId) { - return mComputer.getPackageInfo(packageName, flags, userId); - } - - @Override - public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage, - @PackageManager.PackageInfoFlagsBits long flags, int userId) { - return mComputer.getPackageInfoInternal(versionedPackage.getPackageName(), - versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId); - } - - /** - * Returns whether or not access to the application should be filtered. - *

- * Access may be limited based upon whether the calling or target applications - * are instant applications. - * - * @see #canViewInstantApps(int, int) - */ - private boolean shouldFilterApplication(@Nullable PackageStateInternal ps, int callingUid, - @Nullable ComponentName component, @ComponentType int componentType, int userId) { - return mComputer.shouldFilterApplication(ps, callingUid, - component, componentType, userId); - } - - /** - * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int) - */ - boolean shouldFilterApplication( - @Nullable PackageStateInternal ps, int callingUid, int userId) { - return mComputer.shouldFilterApplication( - ps, callingUid, userId); - } - - /** - * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int) - */ - private boolean shouldFilterApplication(@NonNull SharedUserSetting sus, int callingUid, - int userId) { - return mComputer.shouldFilterApplication(sus, callingUid, userId); - } - - private boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid, - int userId, @PackageManager.ComponentInfoFlagsBits long flags) { - return mComputer.filterSharedLibPackage(ps, uid, userId, flags); - } - - @Override - public String[] currentToCanonicalPackageNames(String[] names) { - return mComputer.currentToCanonicalPackageNames(names); - } - - @Override - public String[] canonicalToCurrentPackageNames(String[] names) { - return mComputer.canonicalToCurrentPackageNames(names); - } - - @Override - public int getPackageUid(@NonNull String packageName, - @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) { - return mComputer.getPackageUid(packageName, flags, userId); - } - int getPackageUidInternal(String packageName, @PackageManager.PackageInfoFlagsBits long flags, int userId, int callingUid) { return mComputer.getPackageUidInternal(packageName, flags, userId, callingUid); } - @Override - public int[] getPackageGids(String packageName, @PackageManager.PackageInfoFlagsBits long flags, - int userId) { - return mComputer.getPackageGids(packageName, flags, userId); - } - - // NOTE: Can't remove due to unsupported app usage - @Override public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) { // Because this is accessed via the package manager service AIDL, // go through the permission manager service AIDL @@ -2730,18 +2599,6 @@ public class PackageManagerService extends IPackageManager.Stub .getPermissionGroupInfo(groupName, flags); } - private ApplicationInfo generateApplicationInfoFromSettings(String packageName, - @PackageManager.ApplicationInfoFlagsBits long flags, int filterCallingUid, int userId) { - return mComputer.generateApplicationInfoFromSettings(packageName, flags, filterCallingUid, - userId); - } - - @Override - public ApplicationInfo getApplicationInfo(String packageName, - @PackageManager.ApplicationInfoFlagsBits long flags, int userId) { - return mComputer.getApplicationInfo(packageName, flags, userId); - } - /** * Important: The provided filterCallingUid is used exclusively to filter out applications * that can be seen based on user state. It's typically the original caller uid prior @@ -2755,61 +2612,6 @@ public class PackageManagerService extends IPackageManager.Stub filterCallingUid, userId); } - @Override - public void deletePreloadsFileCache() { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE, - "deletePreloadsFileCache"); - File dir = Environment.getDataPreloadsFileCacheDirectory(); - Slog.i(TAG, "Deleting preloaded file cache " + dir); - FileUtils.deleteContents(dir); - } - - @Override - public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, - final @StorageManager.AllocateFlags int flags, final IPackageDataObserver observer) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.CLEAR_APP_CACHE, null); - mHandler.post(() -> { - boolean success = false; - try { - freeStorage(volumeUuid, freeStorageSize, flags); - success = true; - } catch (IOException e) { - Slog.w(TAG, e); - } - if (observer != null) { - try { - observer.onRemoveCompleted(null, success); - } catch (RemoteException e) { - Slog.w(TAG, e); - } - } - }); - } - - @Override - public void freeStorage(final String volumeUuid, final long freeStorageSize, - final @StorageManager.AllocateFlags int flags, final IntentSender pi) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.CLEAR_APP_CACHE, TAG); - mHandler.post(() -> { - boolean success = false; - try { - freeStorage(volumeUuid, freeStorageSize, flags); - success = true; - } catch (IOException e) { - Slog.w(TAG, e); - } - if (pi != null) { - try { - pi.sendIntent(null, success ? 1 : 0, null, null, null); - } catch (SendIntentException e) { - Slog.w(TAG, e); - } - } - }); - } - /** * Blocking call to clear all cached app data above quota. */ @@ -2846,7 +2648,7 @@ public class PackageManagerService extends IPackageManager.Stub // 2. Consider preloaded data (after 1w honeymoon, unless aggressive) if (internalVolume && (aggressive || SystemProperties .getBoolean("persist.sys.preloads.file_cache_expired", false))) { - deletePreloadsFileCache(); + mIPackageManager.deletePreloadsFileCache(); if (file.getUsableSpace() >= bytes) return; } @@ -2985,17 +2787,6 @@ public class PackageManagerService extends IPackageManager.Stub wantInstantApps, isImplicitImageCaptureIntentAndNotSetByDpc); } - @Override - public int getTargetSdkVersion(@NonNull String packageName) { - return mComputer.getTargetSdkVersion(packageName); - } - - @Override - public ActivityInfo getActivityInfo(ComponentName component, - @PackageManager.ComponentInfoFlagsBits long flags, int userId) { - return mComputer.getActivityInfo(component, flags, userId); - } - /** * Important: The provided filterCallingUid is used exclusively to filter out activities * that can be seen based on user state. It's typically the original caller uid prior @@ -3008,33 +2799,6 @@ public class PackageManagerService extends IPackageManager.Stub filterCallingUid, userId); } - @Override - public boolean activitySupportsIntent(ComponentName component, Intent intent, - String resolvedType) { - return mComputer.activitySupportsIntent(mResolveComponentName, component, intent, - resolvedType); - } - - @Override - public ActivityInfo getReceiverInfo(ComponentName component, - @PackageManager.ComponentInfoFlagsBits long flags, int userId) { - return mComputer.getReceiverInfo(component, flags, userId); - } - - @Override - public ParceledListSlice getSharedLibraries(String packageName, - @PackageManager.PackageInfoFlagsBits long flags, int userId) { - return mComputer.getSharedLibraries(packageName, flags, userId); - } - - @Nullable - @Override - public ParceledListSlice getDeclaredSharedLibraries( - @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags, - @NonNull int userId) { - return mComputer.getDeclaredSharedLibraries(packageName, flags, userId); - } - @Nullable List getPackagesUsingSharedLibrary( SharedLibraryInfo libInfo, @PackageManager.PackageInfoFlagsBits long flags, @@ -3042,95 +2806,15 @@ public class PackageManagerService extends IPackageManager.Stub return mComputer.getPackagesUsingSharedLibrary(libInfo, flags, callingUid, userId); } - @Nullable - @Override - public ServiceInfo getServiceInfo(@NonNull ComponentName component, - @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) { - return mComputer.getServiceInfo(component, flags, userId); - } - - @Nullable - @Override - public ProviderInfo getProviderInfo(@NonNull ComponentName component, - @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) { - return mComputer.getProviderInfo(component, flags, userId); - } - - @Override - public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) { + public ModuleInfo getModuleInfo(String packageName, @PackageManager.ModuleInfoFlags int flags) { return mModuleInfoProvider.getModuleInfo(packageName, flags); } - @Override - public List getInstalledModules(int flags) { - return mModuleInfoProvider.getInstalledModules(flags); - } - - @Nullable - @Override - public String[] getSystemSharedLibraryNames() { - return mComputer.getSystemSharedLibraryNames(); - } - - @Override - public @NonNull String getServicesSystemSharedLibraryPackageName() { - return mServicesExtensionPackageName; - } - - @Override - public @NonNull String getSharedSystemSharedLibraryPackageName() { - return mSharedSystemSharedLibraryPackageName; - } - @GuardedBy("mLock") void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) { mChangedPackagesTracker.updateSequenceNumber(pkgSetting.getPackageName(), userList); } - @Override - public ChangedPackages getChangedPackages(int sequenceNumber, int userId) { - final int callingUid = Binder.getCallingUid(); - if (getInstantAppPackageName(callingUid) != null) { - return null; - } - if (!mUserManager.exists(userId)) { - return null; - } - enforceCrossUserPermission(callingUid, userId, false, false, "getChangedPackages"); - final ChangedPackages changedPackages = mChangedPackagesTracker.getChangedPackages( - sequenceNumber, userId); - - if (changedPackages != null) { - final List packageNames = changedPackages.getPackageNames(); - for (int index = packageNames.size() - 1; index >= 0; index--) { - // Filter out the changes if the calling package should not be able to see it. - final PackageSetting ps = mSettings.getPackageLPr(packageNames.get(index)); - if (shouldFilterApplication(ps, callingUid, userId)) { - packageNames.remove(index); - } - } - } - - return changedPackages; - } - - @Override - public @NonNull ParceledListSlice getSystemAvailableFeatures() { - // allow instant applications - ArrayList res; - synchronized (mAvailableFeatures) { - res = new ArrayList<>(mAvailableFeatures.size() + 1); - res.addAll(mAvailableFeatures.values()); - } - final FeatureInfo fi = new FeatureInfo(); - fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", - FeatureInfo.GL_ES_VERSION_UNDEFINED); - res.add(fi); - - return new ParceledListSlice<>(res); - } - - @Override public boolean hasSystemFeature(String name, int version) { // allow instant applications synchronized (mAvailableFeatures) { @@ -3144,29 +2828,10 @@ public class PackageManagerService extends IPackageManager.Stub } // NOTE: Can't remove due to unsupported app usage - @Override public int checkPermission(String permName, String pkgName, int userId) { return mPermissionManager.checkPermission(pkgName, permName, userId); } - // NOTE: Can't remove without a major refactor. Keep around for now. - @Override - public int checkUidPermission(String permName, int uid) { - return mComputer.checkUidPermission(permName, uid); - } - - @Override - public String getPermissionControllerPackageName() { - final int callingUid = Binder.getCallingUid(); - if (mComputer.getPackageStateFiltered(mRequiredPermissionControllerPackage, - callingUid, UserHandle.getUserId(callingUid)) != null) { - return mRequiredPermissionControllerPackage; - } - - throw new IllegalStateException("PermissionController is not found"); - } - - @Override public String getSdkSandboxPackageName() { return mRequiredSdkSandboxPackage; } @@ -3175,171 +2840,6 @@ public class PackageManagerService extends IPackageManager.Stub return mRequiredInstallerPackage; } - // NOTE: Can't remove due to unsupported app usage - @Override - public boolean addPermission(PermissionInfo info) { - // Because this is accessed via the package manager service AIDL, - // go through the permission manager service AIDL - return mContext.getSystemService(PermissionManager.class).addPermission(info, false); - } - - // NOTE: Can't remove due to unsupported app usage - @Override - public boolean addPermissionAsync(PermissionInfo info) { - // Because this is accessed via the package manager service AIDL, - // go through the permission manager service AIDL - return mContext.getSystemService(PermissionManager.class).addPermission(info, true); - } - - // NOTE: Can't remove due to unsupported app usage - @Override - public void removePermission(String permName) { - // Because this is accessed via the package manager service AIDL, - // go through the permission manager service AIDL - mContext.getSystemService(PermissionManager.class).removePermission(permName); - } - - // NOTE: Can't remove due to unsupported app usage - @Override - public void grantRuntimePermission(String packageName, String permName, final int userId) { - // Because this is accessed via the package manager service AIDL, - // go through the permission manager service AIDL - mContext.getSystemService(PermissionManager.class) - .grantRuntimePermission(packageName, permName, UserHandle.of(userId)); - } - - @Override - public boolean isProtectedBroadcast(String actionName) { - if (actionName != null) { - // TODO: remove these terrible hacks - if (actionName.startsWith("android.net.netmon.lingerExpired") - || actionName.startsWith("com.android.server.sip.SipWakeupTimer") - || actionName.startsWith("com.android.internal.telephony.data-reconnect") - || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { - return true; - } - } - // allow instant applications - synchronized (mProtectedBroadcasts) { - return mProtectedBroadcasts.contains(actionName); - } - } - - @Override - public int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) { - return mComputer.checkSignatures(pkg1, pkg2); - } - - @Override - public int checkUidSignatures(int uid1, int uid2) { - return mComputer.checkUidSignatures(uid1, uid2); - } - - @Override - public boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate, - @PackageManager.CertificateInputType int type) { - return mComputer.hasSigningCertificate(packageName, certificate, type); - } - - @Override - public boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate, - @PackageManager.CertificateInputType int type) { - return mComputer.hasUidSigningCertificate(uid, certificate, type); - } - - @Override - public List getAllPackages() { - return mComputer.getAllPackages(); - } - - /** - * IMPORTANT: Not all packages returned by this method may be known - * to the system. There are two conditions in which this may occur: - *

    - *
  1. The package is on adoptable storage and the device has been removed
  2. - *
  3. The package is being removed and the internal structures are partially updated
  4. - *
- * The second is an artifact of the current data structures and should be fixed. See - * b/111075456 for one such instance. - * This binder API is cached. If the algorithm in this method changes, - * or if the underlying objecs (as returned by getSettingLPr()) change - * then the logic that invalidates the cache must be revisited. See - * calls to invalidateGetPackagesForUidCache() to locate the points at - * which the cache is invalidated. - */ - @Override - public String[] getPackagesForUid(int uid) { - final int callingUid = Binder.getCallingUid(); - final int userId = UserHandle.getUserId(uid); - enforceCrossUserOrProfilePermission(callingUid, userId, - /* requireFullPermission */ false, - /* checkShell */ false, "getPackagesForUid"); - return mComputer.getPackagesForUid(uid); - } - - @Nullable - @Override - public String getNameForUid(int uid) { - return mComputer.getNameForUid(uid); - } - - @Nullable - @Override - public String[] getNamesForUids(@NonNull int[] uids) { - return mComputer.getNamesForUids(uids); - } - - @Override - public int getUidForSharedUser(@NonNull String sharedUserName) { - return mComputer.getUidForSharedUser(sharedUserName); - } - - @Override - public int getFlagsForUid(int uid) { - return mComputer.getFlagsForUid(uid); - } - - @Override - public int getPrivateFlagsForUid(int uid) { - return mComputer.getPrivateFlagsForUid(uid); - } - - @Override - public boolean isUidPrivileged(int uid) { - return mComputer.isUidPrivileged(uid); - } - - // NOTE: Can't remove due to unsupported app usage - @NonNull - @Override - public String[] getAppOpPermissionPackages(@NonNull String permissionName) { - return mComputer.getAppOpPermissionPackages(permissionName); - } - - @Override - public ResolveInfo resolveIntent(Intent intent, String resolvedType, - @PackageManager.ResolveInfoFlagsBits long flags, int userId) { - return mResolveIntentHelper.resolveIntentInternal(snapshotComputer(), intent, resolvedType, - flags, 0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid()); - } - - @Override - public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) { - return mPreferredActivityHelper.findPersistentPreferredActivity(intent, userId); - } - - @Override - public void setLastChosenActivity(Intent intent, String resolvedType, int flags, - IntentFilter filter, int match, ComponentName activity) { - mPreferredActivityHelper.setLastChosenActivity(intent, resolvedType, flags, - new WatchedIntentFilter(filter), match, activity); - } - - @Override - public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { - return mPreferredActivityHelper.getLastChosenActivity(intent, resolvedType, flags); - } - private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, Intent origIntent, String resolvedType, String callingPackage, @Nullable String callingFeatureId, boolean isRequesterInstantApp, @@ -3394,38 +2894,6 @@ public class PackageManagerService extends IPackageManager.Stub removeMatches, debug, userId, queryMayBeFiltered); } - /* - * Returns if intent can be forwarded from the sourceUserId to the targetUserId - */ - @Override - public boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType, - @UserIdInt int sourceUserId, @UserIdInt int targetUserId) { - return mComputer.canForwardTo(intent, resolvedType, sourceUserId, targetUserId); - } - - private UserInfo getProfileParent(int userId) { - return mComputer.getProfileParent(userId); - } - - private List getMatchingCrossProfileIntentFilters(Intent intent, - String resolvedType, int userId) { - return mComputer.getMatchingCrossProfileIntentFilters(intent, - resolvedType, userId); - } - - @Override - public @NonNull ParceledListSlice queryIntentActivities(Intent intent, - String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { - try { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); - - return new ParceledListSlice<>(snapshotComputer().queryIntentActivitiesInternal(intent, - resolvedType, flags, userId)); - } finally { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } - } - /** * Returns the package name of the calling Uid if it's an instant app. If it isn't * instant, returns {@code null}. @@ -3434,36 +2902,11 @@ public class PackageManagerService extends IPackageManager.Stub return mComputer.getInstantAppPackageName(callingUid); } - @Override - public @NonNull ParceledListSlice queryIntentActivityOptions(ComponentName caller, - Intent[] specifics, String[] specificTypes, Intent intent, - String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { - return new ParceledListSlice<>(mResolveIntentHelper.queryIntentActivityOptionsInternal( - snapshotComputer(), caller, specifics, specificTypes, intent, resolvedType, flags, - userId)); - } - - @Override - public @NonNull ParceledListSlice queryIntentReceivers(Intent intent, - String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { + public @NonNull ParceledListSlice queryIntentReceivers(@NonNull Computer snapshot, + Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, + @UserIdInt int userId) { return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal( - snapshotComputer(), intent, resolvedType, flags, userId, Binder.getCallingUid())); - } - - @Override - public ResolveInfo resolveService(Intent intent, String resolvedType, - @PackageManager.ResolveInfoFlagsBits long flags, int userId) { - final int callingUid = Binder.getCallingUid(); - return mResolveIntentHelper.resolveServiceInternal(snapshotComputer(), intent, resolvedType, - flags, userId, callingUid); - } - - @Override - public @NonNull ParceledListSlice queryIntentServices(Intent intent, - String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { - final int callingUid = Binder.getCallingUid(); - return new ParceledListSlice<>(queryIntentServicesInternal( - intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/)); + snapshot, intent, resolvedType, flags, userId, Binder.getCallingUid())); } @NonNull List queryIntentServicesInternal(Intent intent, @@ -3474,163 +2917,16 @@ public class PackageManagerService extends IPackageManager.Stub includeInstantApps); } - @Override - public @NonNull ParceledListSlice queryIntentContentProviders(Intent intent, - String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { - return new ParceledListSlice<>(mResolveIntentHelper.queryIntentContentProvidersInternal( - snapshotComputer(), intent, resolvedType, flags, userId)); - } - - @Override - public ParceledListSlice getInstalledPackages( - @PackageManager.PackageInfoFlagsBits long flags, int userId) { - return mComputer.getInstalledPackages(flags, userId); - } - - @Override - public ParceledListSlice getPackagesHoldingPermissions( - @NonNull String[] permissions, @PackageManager.PackageInfoFlagsBits long flags, - @UserIdInt int userId) { - return mComputer.getPackagesHoldingPermissions(permissions, flags, userId); - } - - @Override - public ParceledListSlice getInstalledApplications( - @PackageManager.ApplicationInfoFlagsBits long flags, int userId) { - final int callingUid = Binder.getCallingUid(); - return new ParceledListSlice<>( - mComputer.getInstalledApplications(flags, userId, callingUid)); - } - - @Override - public ParceledListSlice getInstantApps(int userId) { - if (HIDE_EPHEMERAL_APIS) { - return null; - } - if (!canViewInstantApps(Binder.getCallingUid(), userId)) { - mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, - "getEphemeralApplications"); - } - enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, - false /* checkShell */, "getEphemeralApplications"); - - Computer computer = snapshotComputer(); - List instantApps = mInstantAppRegistry.getInstantApps(computer, userId); - if (instantApps != null) { - return new ParceledListSlice<>(instantApps); - } - return null; - } - - @Override - public boolean isInstantApp(String packageName, int userId) { - return mComputer.isInstantApp(packageName, userId); - } - private boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid) { return mComputer.isInstantAppInternal(packageName, userId, callingUid); } - @Override - public byte[] getInstantAppCookie(String packageName, int userId) { - if (HIDE_EPHEMERAL_APIS) { - return null; - } - - enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, - false /* checkShell */, "getInstantAppCookie"); - if (!isCallerSameApp(packageName, Binder.getCallingUid())) { - return null; - } - PackageStateInternal packageState = getPackageStateInternal(packageName); - if (packageState == null || packageState.getPkg() == null) { - return null; - } - return mInstantAppRegistry.getInstantAppCookie(packageState.getPkg(), userId); - } - - @Override - public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) { - if (HIDE_EPHEMERAL_APIS) { - return true; - } - - enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, - true /* checkShell */, "setInstantAppCookie"); - if (!isCallerSameApp(packageName, Binder.getCallingUid())) { - return false; - } - - PackageStateInternal packageState = getPackageStateInternal(packageName); - if (packageState == null || packageState.getPkg() == null) { - return false; - } - return mInstantAppRegistry.setInstantAppCookie(packageState.getPkg(), cookie, - mContext.getPackageManager().getInstantAppCookieMaxBytes(), userId); - } - - @Override - public Bitmap getInstantAppIcon(String packageName, int userId) { - if (HIDE_EPHEMERAL_APIS) { - return null; - } - - if (!canViewInstantApps(Binder.getCallingUid(), userId)) { - mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, - "getInstantAppIcon"); - } - enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, - false /* checkShell */, "getInstantAppIcon"); - - return mInstantAppRegistry.getInstantAppIcon(packageName, userId); - } - boolean isCallerSameApp(String packageName, int uid) { return mComputer.isCallerSameApp(packageName, uid); } - @Override - public @NonNull ParceledListSlice getPersistentApplications(int flags) { - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { - return ParceledListSlice.emptyList(); - } - return new ParceledListSlice<>(mComputer.getPersistentApplications(mSafeMode, flags)); - } - - @Override - public ProviderInfo resolveContentProvider(String name, - @PackageManager.ResolveInfoFlagsBits long flags, int userId) { - return mComputer.resolveContentProvider(name, flags, userId, Binder.getCallingUid()); - } - - @Deprecated - public void querySyncProviders(List outNames, List outInfo) { - mComputer.querySyncProviders(mSafeMode, outNames, outInfo); - } - - @NonNull - @Override - public ParceledListSlice queryContentProviders(@Nullable String processName, - int uid, @PackageManager.ComponentInfoFlagsBits long flags, - @Nullable String metaDataKey) { - return mComputer.queryContentProviders(processName, uid, flags, metaDataKey); - } - - @Nullable - @Override - public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) { - return mComputer.getInstrumentationInfo(component, flags); - } - - @NonNull - @Override - public ParceledListSlice queryInstrumentation( - @NonNull String targetPackage, int flags) { - return mComputer.queryInstrumentation(targetPackage, flags); - } - public static void reportSettingsProblem(int priority, String msg) { logCriticalInfo(priority, msg); } @@ -3680,7 +2976,6 @@ public class PackageManagerService extends IPackageManager.Stub requireFullPermission, checkShell, message); } - @Override public void performFstrimIfNeeded() { PackageManagerServiceUtils.enforceSystemOrRoot("Only the system can request fstrim"); @@ -3722,28 +3017,10 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override public void updatePackagesIfNeeded() { mDexOptHelper.performPackageDexOptUpgradeIfNeeded(); } - @Override - public void notifyPackageUse(String packageName, int reason) { - final int callingUid = Binder.getCallingUid(); - final int callingUserId = UserHandle.getUserId(callingUid); - Computer computer = snapshotComputer(); - final boolean notify; - if (getInstantAppPackageName(callingUid) != null) { - notify = isCallerSameApp(packageName, callingUid); - } else { - notify = !isInstantAppInternal(packageName, callingUserId, Process.SYSTEM_UID); - } - if (!notify) { - return; - } - - notifyPackageUseInternal(packageName, reason); - } private void notifyPackageUseInternal(String packageName, int reason) { long time = System.currentTimeMillis(); @@ -3752,103 +3029,6 @@ public class PackageManagerService extends IPackageManager.Stub }); } - @Override - public void notifyDexLoad(String loadingPackageName, Map classLoaderContextMap, - String loaderIsa) { - int callingUid = Binder.getCallingUid(); - if (PLATFORM_PACKAGE_NAME.equals(loadingPackageName) && callingUid != Process.SYSTEM_UID) { - Slog.w(TAG, "Non System Server process reporting dex loads as system server. uid=" - + callingUid); - // Do not record dex loads from processes pretending to be system server. - // Only the system server should be assigned the package "android", so reject calls - // that don't satisfy the constraint. - // - // notifyDexLoad is a PM API callable from the app process. So in theory, apps could - // craft calls to this API and pretend to be system server. Doing so poses no particular - // danger for dex load reporting or later dexopt, however it is a sensible check to do - // in order to verify the expectations. - return; - } - - int userId = UserHandle.getCallingUserId(); - ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId); - if (ai == null) { - Slog.w(TAG, "Loading a package that does not exist for the calling user. package=" - + loadingPackageName + ", user=" + userId); - return; - } - mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId, - Process.isIsolated(callingUid)); - } - - @Override - public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule, - IDexModuleRegisterCallback callback) { - int userId = UserHandle.getCallingUserId(); - ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId); - DexManager.RegisterDexModuleResult result; - if (ai == null) { - Slog.w(TAG, "Registering a dex module for a package that does not exist for the" + - " calling user. package=" + packageName + ", user=" + userId); - result = new DexManager.RegisterDexModuleResult(false, "Package not installed"); - } else { - result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId); - } - - if (callback != null) { - mHandler.post(() -> { - try { - callback.onDexModuleRegistered(dexModulePath, result.success, result.message); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e); - } - }); - } - } - - /** - * Ask the package manager to perform a dex-opt with the given compiler filter. - * - * Note: exposed only for the shell command to allow moving packages explicitly to a - * definite state. - */ - @Override - public boolean performDexOptMode(String packageName, - boolean checkProfiles, String targetCompilerFilter, boolean force, - boolean bootComplete, String splitName) { - return mDexOptHelper.performDexOptMode(packageName, checkProfiles, targetCompilerFilter, - force, bootComplete, splitName); - } - - /** - * Ask the package manager to perform a dex-opt with the given compiler filter on the - * secondary dex files belonging to the given package. - * - * Note: exposed only for the shell command to allow moving packages explicitly to a - * definite state. - */ - @Override - public boolean performDexOptSecondary(String packageName, String compilerFilter, - boolean force) { - return mDexOptHelper.performDexOptSecondary(packageName, compilerFilter, force); - } - - /** - * Reconcile the information we have about the secondary dex files belonging to - * {@code packageName} and the actual dex files. For all dex files that were - * deleted, update the internal records and delete the generated oat files. - */ - @Override - public void reconcileSecondaryDexFiles(String packageName) { - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { - return; - } else if (isInstantAppInternal( - packageName, UserHandle.getCallingUserId(), Process.SYSTEM_UID)) { - return; - } - mDexManager.reconcileSecondaryDexFiles(packageName); - } - /*package*/ DexManager getDexManager() { return mDexManager; } @@ -3879,67 +3059,10 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public void dumpProfiles(String packageName) { - /* Only the shell, root, or the app user should be able to dump profiles. */ - final int callingUid = Binder.getCallingUid(); - final String[] callerPackageNames = getPackagesForUid(callingUid); - if (callingUid != Process.SHELL_UID - && callingUid != Process.ROOT_UID - && !ArrayUtils.contains(callerPackageNames, packageName)) { - throw new SecurityException("dumpProfiles"); - } - - AndroidPackage pkg = getPackage(packageName); - if (pkg == null) { - throw new IllegalArgumentException("Unknown package: " + packageName); - } - - synchronized (mInstallLock) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); - mArtManagerService.dumpProfiles(pkg); - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } - } - - @Override - public void forceDexOpt(String packageName) { - mDexOptHelper.forceDexOpt(packageName); - } - int[] resolveUserIds(int userId) { return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId }; } - @Override - public Property getProperty(String propertyName, String packageName, String className) { - Objects.requireNonNull(propertyName); - Objects.requireNonNull(packageName); - PackageStateInternal packageState = mComputer.getPackageStateFiltered(packageName, - Binder.getCallingUid(), UserHandle.getCallingUserId()); - if (packageState == null) { - return null; - } - return mPackageProperty.getProperty(propertyName, packageName, className); - } - - @Override - public ParceledListSlice queryProperty( - String propertyName, @PropertyLocation int componentType) { - Objects.requireNonNull(propertyName); - final int callingUid = Binder.getCallingUid(); - final int callingUserId = UserHandle.getCallingUserId(); - final List result = - mPackageProperty.queryProperty(propertyName, componentType, packageName -> { - final PackageStateInternal ps = getPackageStateInternal(packageName); - return shouldFilterApplication(ps, callingUid, callingUserId); - }); - if (result == null) { - return ParceledListSlice.emptyList(); - } - return new ParceledListSlice<>(result); - } - private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) { if (installerActivity == null) { if (DEBUG_INSTANT) { @@ -4059,159 +3182,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, - int userId) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); - final int callingUid = Binder.getCallingUid(); - enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */, - true /* checkShell */, "setApplicationHiddenSetting for user " + userId); - - if (hidden && isPackageDeviceAdmin(packageName, userId)) { - Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); - return false; - } - - // Do not allow "android" is being disabled - if ("android".equals(packageName)) { - Slog.w(TAG, "Cannot hide package: android"); - return false; - } - - final long callingId = Binder.clearCallingIdentity(); - try { - final PackageStateInternal packageState = - mComputer.getPackageStateFiltered(packageName, callingUid, userId); - if (packageState == null) { - return false; - } - - // Cannot hide static shared libs as they are considered - // a part of the using app (emulating static linking). Also - // static libs are installed always on internal storage. - AndroidPackage pkg = packageState.getPkg(); - if (pkg != null) { - // Cannot hide SDK libs as they are controlled by SDK manager. - if (pkg.getSdkLibName() != null) { - Slog.w(TAG, "Cannot hide package: " + packageName - + " providing SDK library: " - + pkg.getSdkLibName()); - return false; - } - // Cannot hide static shared libs as they are considered - // a part of the using app (emulating static linking). Also - // static libs are installed always on internal storage. - if (pkg.getStaticSharedLibName() != null) { - Slog.w(TAG, "Cannot hide package: " + packageName - + " providing static shared library: " - + pkg.getStaticSharedLibName()); - return false; - } - } - // Only allow protected packages to hide themselves. - if (hidden && !UserHandle.isSameApp(callingUid, packageState.getAppId()) - && mProtectedPackages.isPackageStateProtected(userId, packageName)) { - Slog.w(TAG, "Not hiding protected package: " + packageName); - return false; - } - - if (packageState.getUserStateOrDefault(userId).isHidden() == hidden) { - return false; - } - - commitPackageStateMutation(null, packageName, packageState1 -> - packageState1.userState(userId).setHidden(hidden)); - - final PackageStateInternal newPackageState = getPackageStateInternal(packageName); - - if (hidden) { - killApplication(packageName, newPackageState.getAppId(), userId, "hiding pkg"); - sendApplicationHiddenForUser(packageName, newPackageState, userId); - } else { - sendPackageAddedForUser(packageName, newPackageState, userId, DataLoaderType.NONE); - } - - scheduleWritePackageRestrictions(userId); - return true; - } finally { - Binder.restoreCallingIdentity(callingId); - } - } - - @Override - public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) { - final int callingUid = Binder.getCallingUid(); - final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID - || callingUid == Process.SYSTEM_UID; - if (!calledFromSystemOrPhone) { - mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, - "setSystemAppHiddenUntilInstalled"); - } - - final PackageStateInternal stateRead = getPackageStateInternal(packageName); - if (stateRead == null || !stateRead.isSystem() || stateRead.getPkg() == null) { - return; - } - if (stateRead.getPkg().isCoreApp() && !calledFromSystemOrPhone) { - throw new SecurityException("Only system or phone callers can modify core apps"); - } - - commitPackageStateMutation(null, mutator -> { - mutator.forPackage(packageName) - .setHiddenUntilInstalled(hidden); - mutator.forDisabledSystemPackage(packageName) - .setHiddenUntilInstalled(hidden); - }); - } - - @Override - public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) { - final int callingUid = Binder.getCallingUid(); - final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID - || callingUid == Process.SYSTEM_UID; - if (!calledFromSystemOrPhone) { - mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, - "setSystemAppHiddenUntilInstalled"); - } - - final PackageStateInternal packageState = getPackageStateInternal(packageName); - // The target app should always be in system - if (packageState == null || !packageState.isSystem() || packageState.getPkg() == null) { - return false; - } - if (packageState.getPkg().isCoreApp() && !calledFromSystemOrPhone) { - throw new SecurityException("Only system or phone callers can modify core apps"); - } - // Check if the install state is the same - if (packageState.getUserStateOrDefault(userId).isInstalled() == installed) { - return false; - } - - final long callingId = Binder.clearCallingIdentity(); - try { - if (installed) { - // install the app from uninstalled state - installExistingPackageAsUser( - packageName, - userId, - PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS, - PackageManager.INSTALL_REASON_DEVICE_SETUP, - null); - return true; - } - - // uninstall the app from installed state - deletePackageVersioned( - new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST), - new LegacyPackageDeleteObserver(null).getBinder(), - userId, - PackageManager.DELETE_SYSTEM_APP); - return true; - } finally { - Binder.restoreCallingIdentity(callingId); - } - } - private void sendApplicationHiddenForUser(String packageName, PackageStateInternal packageState, int userId) { final PackageRemovedInfo info = new PackageRemovedInfo(this); @@ -4223,26 +3193,6 @@ public class PackageManagerService extends IPackageManager.Stub info.sendPackageRemovedBroadcasts(true /*killApp*/, false /*removedBySystem*/); } - /** - * Returns true if application is not found or there was an error. Otherwise it returns - * the hidden state of the package for the given user. - */ - @Override - public boolean getApplicationHiddenSettingAsUser(@NonNull String packageName, - @UserIdInt int userId) { - return mComputer.getApplicationHiddenSettingAsUser(packageName, userId); - } - - /** - * @hide - */ - @Override - public int installExistingPackageAsUser(String packageName, int userId, int installFlags, - int installReason, List whiteListedPermissions) { - return mInstallPackageHelper.installExistingPackageAsUser(packageName, userId, installFlags, - installReason, whiteListedPermissions, null); - } - boolean isUserRestricted(int userId, String restrictionKey) { Bundle restrictions = mUserManager.getUserRestrictions(userId); if (restrictions.getBoolean(restrictionKey, false)) { @@ -4252,77 +3202,6 @@ public class PackageManagerService extends IPackageManager.Stub return false; } - @Override - public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames, - int restrictionFlags, int userId) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS, - "setDistractingPackageRestrictionsAsUser"); - - final int callingUid = Binder.getCallingUid(); - if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID - && UserHandle.getUserId(callingUid) != userId) { - throw new SecurityException("Calling uid " + callingUid + " cannot call for user " - + userId); - } - Objects.requireNonNull(packageNames, "packageNames cannot be null"); - if (restrictionFlags != 0 - && !mSuspendPackageHelper.isSuspendAllowedForUser(userId, callingUid)) { - Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId); - return packageNames; - } - - final List changedPackagesList = new ArrayList<>(packageNames.length); - final IntArray changedUids = new IntArray(packageNames.length); - final List unactionedPackages = new ArrayList<>(packageNames.length); - - ArraySet changesToCommit = new ArraySet<>(); - Computer computer = snapshotComputer(); - final boolean[] canRestrict = (restrictionFlags != 0) - ? mSuspendPackageHelper.canSuspendPackageForUser(computer, packageNames, userId, - callingUid) : null; - for (int i = 0; i < packageNames.length; i++) { - final String packageName = packageNames[i]; - final PackageStateInternal packageState = - computer.getPackageStateInternal(packageName); - if (packageState == null - || computer.shouldFilterApplication(packageState, callingUid, userId)) { - Slog.w(TAG, "Could not find package setting for package: " + packageName - + ". Skipping..."); - unactionedPackages.add(packageName); - continue; - } - if (canRestrict != null && !canRestrict[i]) { - unactionedPackages.add(packageName); - continue; - } - final int oldDistractionFlags = packageState.getUserStateOrDefault(userId) - .getDistractionFlags(); - if (restrictionFlags != oldDistractionFlags) { - changedPackagesList.add(packageName); - changedUids.add(UserHandle.getUid(userId, packageState.getAppId())); - changesToCommit.add(packageName); - } - } - - commitPackageStateMutation(null, mutator -> { - final int size = changesToCommit.size(); - for (int index = 0; index < size; index++) { - mutator.forPackage(changesToCommit.valueAt(index)) - .userState(userId) - .setDistractionFlags(restrictionFlags); - } - }); - - if (!changedPackagesList.isEmpty()) { - final String[] changedPackages = changedPackagesList.toArray( - new String[changedPackagesList.size()]); - mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged( - changedPackages, changedUids.toArray(), userId, restrictionFlags)); - scheduleWritePackageRestrictions(userId); - } - return unactionedPackages.toArray(new String[0]); - } - private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid, int userId, String callingMethod) { if (callingUid == Process.ROOT_UID @@ -4333,7 +3212,7 @@ public class PackageManagerService extends IPackageManager.Stub final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId); if (ownerPackage != null) { - final int ownerUid = getPackageUid(ownerPackage, 0, userId); + final int ownerUid = mIPackageManager.getPackageUid(ownerPackage, 0, userId); if (ownerUid == callingUid) { return; } @@ -4342,7 +3221,7 @@ public class PackageManagerService extends IPackageManager.Stub mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS, callingMethod); - final int packageUid = getPackageUid(callingPackage, 0, userId); + final int packageUid = mIPackageManager.getPackageUid(callingPackage, 0, userId); final boolean allowedPackageUid = packageUid == callingUid; // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL final boolean allowedShell = callingUid == SHELL_UID @@ -4354,34 +3233,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, - PersistableBundle appExtras, PersistableBundle launcherExtras, - SuspendDialogInfo dialogInfo, String callingPackage, int userId) { - final int callingUid = Binder.getCallingUid(); - enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId, - "setPackagesSuspendedAsUser"); - return mSuspendPackageHelper.setPackagesSuspended(snapshotComputer(), packageNames, - suspended, appExtras, launcherExtras, dialogInfo, callingPackage, userId, - callingUid); - } - - @Override - public Bundle getSuspendedPackageAppExtras(String packageName, int userId) { - final int callingUid = Binder.getCallingUid(); - if (getPackageUid(packageName, 0, userId) != callingUid) { - throw new SecurityException("Calling package " + packageName - + " does not belong to calling uid " + callingUid); - } - return mSuspendPackageHelper.getSuspendedPackageAppExtras( - packageName, userId, callingUid); - } - - @Override - public boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId) { - return mComputer.isPackageSuspendedForUser(packageName, userId); - } - void unsuspendForSuspendingPackage(@NonNull Computer computer, String suspendingPackage, @UserIdInt int userId) { // TODO: This can be replaced by a special parameter to iterate all packages, rather than @@ -4436,67 +3287,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) { - Objects.requireNonNull(packageNames, "packageNames cannot be null"); - mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, - "getUnsuspendablePackagesForUser"); - final int callingUid = Binder.getCallingUid(); - if (UserHandle.getUserId(callingUid) != userId) { - throw new SecurityException("Calling uid " + callingUid - + " cannot query getUnsuspendablePackagesForUser for user " + userId); - } - return mSuspendPackageHelper.getUnsuspendablePackagesForUser(snapshotComputer(), - packageNames, userId, callingUid); - } - - @Override - public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, - "Only package verification agents can verify applications"); - final int callingUid = Binder.getCallingUid(); - - final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); - final PackageVerificationResponse response = new PackageVerificationResponse( - verificationCode, callingUid); - msg.arg1 = id; - msg.obj = response; - mHandler.sendMessage(msg); - } - - @Override - public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, - long millisecondsToDelay) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, - "Only package verification agents can extend verification timeouts"); - final int callingUid = Binder.getCallingUid(); - - mHandler.post(() -> { - final PackageVerificationState state = mPendingVerification.get(id); - final PackageVerificationResponse response = new PackageVerificationResponse( - verificationCodeAtTimeout, callingUid); - - long delay = millisecondsToDelay; - if (delay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { - delay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; - } - if (delay < 0) { - delay = 0; - } - - if ((state != null) && !state.timeoutExtended()) { - state.extendTimeout(); - - final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); - msg.arg1 = id; - msg.obj = response; - mHandler.sendMessageDelayed(msg, delay); - } - }); - } - private void setEnableRollbackCode(int token, int enableRollbackCode) { final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS); msg.arg1 = token; @@ -4504,223 +3294,6 @@ public class PackageManagerService extends IPackageManager.Stub mHandler.sendMessage(msg); } - @Override - public void finishPackageInstall(int token, boolean didLaunch) { - PackageManagerServiceUtils.enforceSystemOrRoot( - "Only the system is allowed to finish installs"); - - if (DEBUG_INSTALL) { - Slog.v(TAG, "BM finishing package install for " + token); - } - Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); - - final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); - mHandler.sendMessage(msg); - } - - @Deprecated - @Override - public void verifyIntentFilter(int id, int verificationCode, List failedDomains) { - DomainVerificationProxyV1.queueLegacyVerifyResult(mContext, mDomainVerificationConnection, - id, verificationCode, failedDomains, Binder.getCallingUid()); - } - - @Deprecated - @Override - public int getIntentVerificationStatus(String packageName, int userId) { - return mDomainVerificationManager.getLegacyState(packageName, userId); - } - - @Deprecated - @Override - public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { - return mDomainVerificationManager.setLegacyUserState(packageName, userId, status); - } - - @Deprecated - @Override - public @NonNull ParceledListSlice getIntentFilterVerifications( - String packageName) { - return ParceledListSlice.emptyList(); - } - - @NonNull - @Override - public ParceledListSlice getAllIntentFilters(@NonNull String packageName) { - return mComputer.getAllIntentFilters(packageName); - } - - @Override - public void setInstallerPackageName(String targetPackage, String installerPackageName) { - final int callingUid = Binder.getCallingUid(); - final int callingUserId = UserHandle.getUserId(callingUid); - final FunctionalUtils.ThrowingCheckedFunction - implementation = computer -> { - if (computer.getInstantAppPackageName(callingUid) != null) { - return false; - } - - PackageStateInternal targetPackageState = - computer.getPackageStateInternal(targetPackage); - if (targetPackageState == null - || computer.shouldFilterApplication(targetPackageState, callingUid, - callingUserId)) { - throw new IllegalArgumentException("Unknown target package: " + targetPackage); - } - - PackageStateInternal installerPackageState = null; - if (installerPackageName != null) { - installerPackageState = computer.getPackageStateInternal(installerPackageName); - if (installerPackageState == null - || shouldFilterApplication( - installerPackageState, callingUid, callingUserId)) { - throw new IllegalArgumentException("Unknown installer package: " - + installerPackageName); - } - } - - Signature[] callerSignature; - final int appId = UserHandle.getAppId(callingUid); - Pair either = - computer.getPackageOrSharedUser(appId); - if (either != null) { - if (either.first != null) { - callerSignature = either.first.getSigningDetails().getSignatures(); - } else { - callerSignature = either.second.getSigningDetails().getSignatures(); - } - } else { - throw new SecurityException("Unknown calling UID: " + callingUid); - } - - // Verify: can't set installerPackageName to a package that is - // not signed with the same cert as the caller. - if (installerPackageState != null) { - if (compareSignatures(callerSignature, - installerPackageState.getSigningDetails().getSignatures()) - != PackageManager.SIGNATURE_MATCH) { - throw new SecurityException( - "Caller does not have same cert as new installer package " - + installerPackageName); - } - } - - // Verify: if target already has an installer package, it must - // be signed with the same cert as the caller. - String targetInstallerPackageName = - targetPackageState.getInstallSource().installerPackageName; - PackageStateInternal targetInstallerPkgSetting = targetInstallerPackageName == null - ? null : computer.getPackageStateInternal(targetInstallerPackageName); - - if (targetInstallerPkgSetting != null) { - if (compareSignatures(callerSignature, - targetInstallerPkgSetting.getSigningDetails().getSignatures()) - != PackageManager.SIGNATURE_MATCH) { - throw new SecurityException( - "Caller does not have same cert as old installer package " - + targetInstallerPackageName); - } - } else if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES) - != PERMISSION_GRANTED) { - // This is probably an attempt to exploit vulnerability b/150857253 of taking - // privileged installer permissions when the installer has been uninstalled or - // was never set. - EventLog.writeEvent(0x534e4554, "150857253", callingUid, ""); - - final long binderToken = Binder.clearCallingIdentity(); - try { - if (mInjector.getCompatibility().isChangeEnabledByUid( - THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE, - callingUid)) { - throw new SecurityException("Neither user " + callingUid - + " nor current process has " - + Manifest.permission.INSTALL_PACKAGES); - } else { - // If change disabled, fail silently for backwards compatibility - return false; - } - } finally { - Binder.restoreCallingIdentity(binderToken); - } - } - - return true; - }; - PackageStateMutator.InitialState initialState = recordInitialState(); - boolean allowed = implementation.apply(snapshotComputer()); - if (allowed) { - // TODO: Need to lock around here to handle mSettings.addInstallerPackageNames, - // should find an alternative which avoids any race conditions - PackageStateInternal targetPackageState; - synchronized (mLock) { - PackageStateMutator.Result result = commitPackageStateMutation(initialState, - targetPackage, state -> state.setInstaller(installerPackageName)); - if (result.isPackagesChanged() || result.isStateChanged()) { - synchronized (mPackageStateWriteLock) { - allowed = implementation.apply(snapshotComputer()); - if (allowed) { - commitPackageStateMutation(null, targetPackage, - state -> state.setInstaller(installerPackageName)); - } else { - return; - } - } - } - targetPackageState = getPackageStateInternal(targetPackage); - mSettings.addInstallerPackageNames(targetPackageState.getInstallSource()); - } - mAppsFilter.addPackage(targetPackageState); - scheduleWriteSettings(); - } - } - - @Override - public void setApplicationCategoryHint(String packageName, int categoryHint, - String callerPackageName) { - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { - throw new SecurityException("Instant applications don't have access to this method"); - } - mInjector.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), - callerPackageName); - - final PackageStateMutator.InitialState initialState = recordInitialState(); - - final FunctionalUtils.ThrowingFunction - implementation = computer -> { - PackageStateInternal packageState = computer.getPackageStateFiltered(packageName, - Binder.getCallingUid(), UserHandle.getCallingUserId()); - if (packageState == null) { - throw new IllegalArgumentException("Unknown target package " + packageName); - } - - if (!Objects.equals(callerPackageName, - packageState.getInstallSource().installerPackageName)) { - throw new IllegalArgumentException("Calling package " + callerPackageName - + " is not installer for " + packageName); - } - - if (packageState.getCategoryOverride() != categoryHint) { - return commitPackageStateMutation(initialState, - packageName, state -> state.setCategoryOverride(categoryHint)); - } else { - return null; - } - }; - - PackageStateMutator.Result result = implementation.apply(snapshotComputer()); - if (result != null && result.isStateChanged() && !result.isSpecificPackageNull()) { - // TODO: Specific return value of what state changed? - // The installer on record might have changed, retry with lock - synchronized (mPackageStateWriteLock) { - result = implementation.apply(snapshotComputer()); - } - } - - if (result != null && result.isCommitted()) { - scheduleWriteSettings(); - } - } - /** * Callback from PackageSettings whenever an app is first transitioned out of the * 'stopped' state. Normally we just issue the broadcast, but we can't do that if @@ -4799,21 +3372,12 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public void deletePackageAsUser(String packageName, int versionCode, - IPackageDeleteObserver observer, int userId, int flags) { - deletePackageVersioned(new VersionedPackage(packageName, versionCode), - new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags); - } - - @Override public void deleteExistingPackageAsUser(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId) { mDeletePackageHelper.deleteExistingPackageAsUser( versionedPackage, observer, userId); } - @Override public void deletePackageVersioned(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { mDeletePackageHelper.deletePackageVersionedInternal( @@ -4830,15 +3394,14 @@ public class PackageManagerService extends IPackageManager.Stub boolean isCallerVerifier(int callingUid) { final int callingUserId = UserHandle.getUserId(callingUid); - return mRequiredVerifierPackage != null && - callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId); + return mRequiredVerifierPackage != null && callingUid == mIPackageManager.getPackageUid( + mRequiredVerifierPackage, 0, callingUserId); } - @Override public boolean isPackageDeviceAdminOnAnyUser(String packageName) { final int callingUid = Binder.getCallingUid(); - if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid) - != PERMISSION_GRANTED) { + if (mIPackageManager.checkUidPermission(android.Manifest.permission.MANAGE_USERS, + callingUid) != PERMISSION_GRANTED) { EventLog.writeEvent(0x534e4554, "128599183", -1, ""); throw new SecurityException(android.Manifest.permission.MANAGE_USERS + " permission is required to call this API"); @@ -4893,139 +3456,6 @@ public class PackageManagerService extends IPackageManager.Stub return mDevicePolicyManager; } - @Override - public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, - int userId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.DELETE_PACKAGES, null); - PackageStateInternal packageState = getPackageStateInternal(packageName); - if (packageState != null && packageState.getPkg() != null) { - AndroidPackage pkg = packageState.getPkg(); - // Cannot block uninstall SDK libs as they are controlled by SDK manager. - if (pkg.getSdkLibName() != null) { - Slog.w(TAG, "Cannot block uninstall of package: " + packageName - + " providing SDK library: " + pkg.getSdkLibName()); - return false; - } - // Cannot block uninstall of static shared libs as they are - // considered a part of the using app (emulating static linking). - // Also static libs are installed always on internal storage. - if (pkg.getStaticSharedLibName() != null) { - Slog.w(TAG, "Cannot block uninstall of package: " + packageName - + " providing static shared library: " + pkg.getStaticSharedLibName()); - return false; - } - } - synchronized (mLock) { - mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall); - } - - scheduleWritePackageRestrictions(userId); - return true; - } - - @Override - public boolean getBlockUninstallForUser(@NonNull String packageName, @UserIdInt int userId) { - return mComputer.getBlockUninstallForUser(packageName, userId); - } - - @Override - public boolean setRequiredForSystemUser(String packageName, boolean requiredForSystemUser) { - PackageManagerServiceUtils.enforceSystemOrRoot( - "setRequiredForSystemUser can only be run by the system or root"); - - PackageStateMutator.Result result = commitPackageStateMutation(null, packageName, - packageState -> packageState.setRequiredForSystemUser(requiredForSystemUser)); - if (!result.isCommitted()) { - return false; - } - - scheduleWriteSettings(); - return true; - } - - @Override - public void clearApplicationProfileData(String packageName) { - PackageManagerServiceUtils.enforceSystemOrRoot( - "Only the system can clear all profile data"); - - final AndroidPackage pkg = getPackage(packageName); - try (PackageFreezer ignored = freezePackage(packageName, "clearApplicationProfileData")) { - synchronized (mInstallLock) { - mAppDataHelper.clearAppProfilesLIF(pkg); - } - } - } - - @Override - public void clearApplicationUserData(final String packageName, - final IPackageDataObserver observer, final int userId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.CLEAR_APP_USER_DATA, null); - - final int callingUid = Binder.getCallingUid(); - enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */, - false /* checkShell */, "clear application data"); - - if (mComputer.getPackageStateFiltered(packageName, callingUid, userId) == null) { - if (observer != null) { - mHandler.post(() -> { - try { - observer.onRemoveCompleted(packageName, false); - } catch (RemoteException e) { - Log.i(TAG, "Observer no longer exists."); - } - }); - } - return; - } - if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { - throw new SecurityException("Cannot clear data for a protected package: " - + packageName); - } - - // Queue up an async operation since the package deletion may take a little while. - mHandler.post(new Runnable() { - public void run() { - mHandler.removeCallbacks(this); - final boolean succeeded; - try (PackageFreezer freezer = freezePackage(packageName, - "clearApplicationUserData")) { - synchronized (mInstallLock) { - succeeded = clearApplicationUserDataLIF(packageName, userId); - } - mInstantAppRegistry.deleteInstantApplicationMetadata(packageName, userId); - synchronized (mLock) { - if (succeeded) { - resetComponentEnabledSettingsIfNeededLPw(packageName, userId); - } - } - } - if (succeeded) { - // invoke DeviceStorageMonitor's update method to clear any notifications - DeviceStorageMonitorInternal dsm = LocalServices - .getService(DeviceStorageMonitorInternal.class); - if (dsm != null) { - dsm.checkMemory(); - } - if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId) - == PERMISSION_GRANTED) { - unsuspendForSuspendingPackage(snapshotComputer(), packageName, userId); - removeAllDistractingPackageRestrictions(userId); - flushPackageRestrictionsAsUserInternalLocked(userId); - } - } - if (observer != null) { - try { - observer.onRemoveCompleted(packageName, succeeded); - } catch (RemoteException e) { - Log.i(TAG, "Observer no longer exists."); - } - } //end if observer - } //end run - }); - } - private boolean clearApplicationUserDataLIF(String packageName, int userId) { if (packageName == null) { Slog.w(TAG, "Attempt to delete null packageName."); @@ -5108,106 +3538,14 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public void deleteApplicationCacheFiles(final String packageName, - final IPackageDataObserver observer) { - final int userId = UserHandle.getCallingUserId(); - deleteApplicationCacheFilesAsUser(packageName, userId, observer); - } - - @Override - public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, - final IPackageDataObserver observer) { - final int callingUid = Binder.getCallingUid(); - if (mContext.checkCallingOrSelfPermission( - android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES) - != PackageManager.PERMISSION_GRANTED) { - // If the caller has the old delete cache permission, silently ignore. Else throw. - if (mContext.checkCallingOrSelfPermission( - android.Manifest.permission.DELETE_CACHE_FILES) - == PackageManager.PERMISSION_GRANTED) { - Slog.w(TAG, "Calling uid " + callingUid + " does not have " + - android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES + - ", silently ignoring"); - return; - } - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null); - } - enforceCrossUserPermission(callingUid, userId, /* requireFullPermission= */ true, - /* checkShell= */ false, "delete application cache files"); - final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission( - android.Manifest.permission.ACCESS_INSTANT_APPS); - - final AndroidPackage pkg = getPackage(packageName); - - // Queue up an async operation since the package deletion may take a little while. - mHandler.post(() -> { - final PackageStateInternal ps = - pkg == null ? null : getPackageStateInternal(pkg.getPackageName()); - boolean doClearData = true; - if (ps != null) { - final boolean targetIsInstantApp = - ps.getUserStateOrDefault(UserHandle.getUserId(callingUid)).isInstantApp(); - doClearData = !targetIsInstantApp - || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED; - } - if (doClearData) { - synchronized (mInstallLock) { - final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL; - // We're only clearing cache files, so we don't care if the - // app is unfrozen and still able to run - mAppDataHelper.clearAppDataLIF(pkg, userId, - flags | Installer.FLAG_CLEAR_CACHE_ONLY); - mAppDataHelper.clearAppDataLIF(pkg, userId, - flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); - } - } - if (observer != null) { - try { - observer.onRemoveCompleted(packageName, true); - } catch (RemoteException e) { - Log.i(TAG, "Observer no longer exists."); - } - } - }); - } - - @Override - public void getPackageSizeInfo(final String packageName, int userId, - final IPackageStatsObserver observer) { - throw new UnsupportedOperationException( - "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!"); - } - int getUidTargetSdkVersion(int uid) { return mComputer.getUidTargetSdkVersion(uid); } - @Override - public void addPreferredActivity(IntentFilter filter, int match, - ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) { - mPreferredActivityHelper.addPreferredActivity( - new WatchedIntentFilter(filter), match, set, activity, true, userId, - "Adding preferred", removeExisting); - } - void postPreferredActivityChangedBroadcast(int userId) { mHandler.post(() -> mBroadcastHelper.sendPreferredActivityChangedBroadcast(userId)); } - @Override - public void replacePreferredActivity(IntentFilter filter, int match, - ComponentName[] set, ComponentName activity, int userId) { - mPreferredActivityHelper.replacePreferredActivity(new WatchedIntentFilter(filter), match, - set, activity, userId); - } - - @Override - public void clearPackagePreferredActivities(String packageName) { - mPreferredActivityHelper.clearPackagePreferredActivities(packageName); - } - /** This method takes a specific user id as well as UserHandle.USER_ALL. */ @GuardedBy("mLock") @@ -5227,109 +3565,6 @@ public class PackageManagerService extends IPackageManager.Stub mPreferredActivityHelper.updateDefaultHomeNotLocked(userId); } - @Override - public void resetApplicationPreferences(int userId) { - mPreferredActivityHelper.resetApplicationPreferences(userId); - } - - @Override - public int getPreferredActivities(List outFilters, - List outActivities, String packageName) { - return mPreferredActivityHelper.getPreferredActivities(outFilters, outActivities, - packageName, mComputer); - } - - @Override - public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, - int userId) { - mPreferredActivityHelper.addPersistentPreferredActivity(new WatchedIntentFilter(filter), - activity, userId); - } - - @Override - public void clearPackagePersistentPreferredActivities(String packageName, int userId) { - mPreferredActivityHelper.clearPackagePersistentPreferredActivities(packageName, userId); - } - - /** - * Non-Binder method, support for the backup/restore mechanism: write the - * full set of preferred activities in its canonical XML format. Returns the - * XML output as a byte array, or null if there is none. - */ - @Override - public byte[] getPreferredActivityBackup(int userId) { - return mPreferredActivityHelper.getPreferredActivityBackup(userId); - } - - @Override - public void restorePreferredActivities(byte[] backup, int userId) { - mPreferredActivityHelper.restorePreferredActivities(backup, userId); - } - - /** - * Non-Binder method, support for the backup/restore mechanism: write the - * default browser (etc) settings in its canonical XML format. Returns the default - * browser XML representation as a byte array, or null if there is none. - */ - @Override - public byte[] getDefaultAppsBackup(int userId) { - return mPreferredActivityHelper.getDefaultAppsBackup(userId); - } - - @Override - public void restoreDefaultApps(byte[] backup, int userId) { - mPreferredActivityHelper.restoreDefaultApps(backup, userId); - } - - @Override - public byte[] getDomainVerificationBackup(int userId) { - if (Binder.getCallingUid() != Process.SYSTEM_UID) { - throw new SecurityException("Only the system may call getDomainVerificationBackup()"); - } - - try { - try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { - TypedXmlSerializer serializer = Xml.resolveSerializer(output); - mDomainVerificationManager.writeSettings(snapshotComputer(), serializer, true, - userId); - return output.toByteArray(); - } - } catch (Exception e) { - if (DEBUG_BACKUP) { - Slog.e(TAG, "Unable to write domain verification for backup", e); - } - return null; - } - } - - @Override - public void restoreDomainVerification(byte[] backup, int userId) { - if (Binder.getCallingUid() != Process.SYSTEM_UID) { - throw new SecurityException("Only the system may call restorePreferredActivities()"); - } - - try { - ByteArrayInputStream input = new ByteArrayInputStream(backup); - TypedXmlPullParser parser = Xml.resolvePullParser(input); - - // User ID input isn't necessary here as it assumes the user integers match and that - // the only states inside the backup XML are for the target user. - mDomainVerificationManager.restoreSettings(snapshotComputer(), parser); - input.close(); - } catch (Exception e) { - if (DEBUG_BACKUP) { - Slog.e(TAG, "Exception restoring domain verification: " + e.getMessage()); - } - } - } - - @Override - public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, - int sourceUserId, int targetUserId, int flags) { - addCrossProfileIntentFilter(new WatchedIntentFilter(intentFilter), ownerPackage, - sourceUserId, targetUserId, flags); - } - /** * Variant that takes a {@link WatchedIntentFilter} */ @@ -5365,55 +3600,25 @@ public class PackageManagerService extends IPackageManager.Stub scheduleWritePackageRestrictions(sourceUserId); } - @Override - public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); - final int callingUid = Binder.getCallingUid(); - enforceOwnerRights(ownerPackage, callingUid); - PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(), - UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); - synchronized (mLock) { - CrossProfileIntentResolver resolver = - mSettings.editCrossProfileIntentResolverLPw(sourceUserId); - ArraySet set = - new ArraySet<>(resolver.filterSet()); - for (CrossProfileIntentFilter filter : set) { - if (filter.getOwnerPackage().equals(ownerPackage)) { - resolver.removeFilter(filter); - } - } - } - scheduleWritePackageRestrictions(sourceUserId); - } - // Enforcing that callingUid is owning pkg on userId private void enforceOwnerRights(String pkg, int callingUid) { // The system owns everything. if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { return; } - final String[] callerPackageNames = getPackagesForUid(callingUid); + final String[] callerPackageNames = mIPackageManager.getPackagesForUid(callingUid); if (!ArrayUtils.contains(callerPackageNames, pkg)) { throw new SecurityException("Calling uid " + callingUid + " does not own package " + pkg); } final int callingUserId = UserHandle.getUserId(callingUid); - PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); + PackageInfo pi = mIPackageManager.getPackageInfo(pkg, 0, callingUserId); if (pi == null) { throw new IllegalArgumentException("Unknown package " + pkg + " on user " + callingUserId); } } - @Override - public ComponentName getHomeActivities(List allHomeCandidates) { - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { - return null; - } - return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); - } - public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) { UserManagerService ums = UserManagerService.getInstance(); if (ums == null || sessionInfo.isStaged()) { @@ -5444,11 +3649,6 @@ public class PackageManagerService extends IPackageManager.Stub userId); } - @Override - public void setHomeActivity(ComponentName comp, int userId) { - mPreferredActivityHelper.setHomeActivity(comp, userId); - } - private @Nullable String getSetupWizardPackageNameImpl(@NonNull Computer computer) { final Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); @@ -5500,84 +3700,17 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public String getDefaultTextClassifierPackageName() { - return ensureSystemPackageName( - mContext.getString(R.string.config_servicesExtensionPackage)); - } - - @Override - public String getSystemTextClassifierPackageName() { - return ensureSystemPackageName( - mContext.getString(R.string.config_defaultTextClassifierPackage)); - } - - @Override - public @Nullable String getAttentionServicePackageName() { - return ensureSystemPackageName( - getPackageFromComponentString(R.string.config_defaultAttentionService)); - } - - @Override - public @Nullable String getRotationResolverPackageName() { - return ensureSystemPackageName( - getPackageFromComponentString(R.string.config_defaultRotationResolverService)); - } - @Nullable private String getDeviceConfiguratorPackageName() { return ensureSystemPackageName(mContext.getString( R.string.config_deviceConfiguratorPackageName)); } - @Override - public String getWellbeingPackageName() { - final long identity = Binder.clearCallingIdentity(); - try { - return CollectionUtils.firstOrNull( - mContext.getSystemService(RoleManager.class).getRoleHolders( - RoleManager.ROLE_SYSTEM_WELLBEING)); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public String getAppPredictionServicePackageName() { - return ensureSystemPackageName( - getPackageFromComponentString(R.string.config_defaultAppPredictionService)); - } - - @Override - public String getSystemCaptionsServicePackageName() { - return ensureSystemPackageName( - getPackageFromComponentString(R.string.config_defaultSystemCaptionsService)); - } - - @Override - public String getSetupWizardPackageName() { - if (Binder.getCallingUid() != Process.SYSTEM_UID) { - throw new SecurityException("Non-system caller"); - } - return mPmInternal.getSetupWizardPackageName(); - } - public @Nullable String getAmbientContextDetectionPackageName() { return ensureSystemPackageName(getPackageFromComponentString( R.string.config_defaultAmbientContextDetectionService)); } - public String getIncidentReportApproverPackageName() { - return ensureSystemPackageName(mContext.getString( - R.string.config_incidentReportApproverPackage)); - } - - @Override - public String getContentCaptureServicePackageName() { - return ensureSystemPackageName( - getPackageFromComponentString(R.string.config_defaultContentCaptureService)); - } - public String getOverlayConfigSignaturePackageName() { return ensureSystemPackageName(mInjector.getSystemConfig() .getOverlayConfigSignaturePackage()); @@ -5645,8 +3778,10 @@ public class PackageManagerService extends IPackageManager.Stub } final long token = Binder.clearCallingIdentity(); try { - if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) { - PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM); + if (mIPackageManager.getPackageInfo(packageName, MATCH_FACTORY_ONLY, + UserHandle.USER_SYSTEM) == null) { + PackageInfo packageInfo = + mIPackageManager.getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM); if (packageInfo != null) { EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid, ""); @@ -5659,39 +3794,6 @@ public class PackageManagerService extends IPackageManager.Stub return packageName; } - @Override - public void setApplicationEnabledSetting(String appPackageName, - int newState, int flags, int userId, String callingPackage) { - if (!mUserManager.exists(userId)) return; - if (callingPackage == null) { - callingPackage = Integer.toString(Binder.getCallingUid()); - } - - setEnabledSettings(List.of(new ComponentEnabledSetting(appPackageName, newState, flags)), - userId, callingPackage); - } - - @Override - public void setUpdateAvailable(String packageName, boolean updateAvailable) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); - commitPackageStateMutation(null, packageName, state -> - state.setUpdateAvailable(updateAvailable)); - } - - @Override - public void overrideLabelAndIcon(@NonNull ComponentName componentName, - @NonNull String nonLocalizedLabel, int icon, int userId) { - if (TextUtils.isEmpty(nonLocalizedLabel)) { - throw new IllegalArgumentException("Override label should be a valid String"); - } - updateComponentLabelIcon(componentName, nonLocalizedLabel, icon, userId); - } - - @Override - public void restoreLabelAndIcon(@NonNull ComponentName componentName, int userId) { - updateComponentLabelIcon(componentName, null, null, userId); - } - @VisibleForTesting(visibility = Visibility.PRIVATE) public void updateComponentLabelIcon(/*@NonNull*/ ComponentName componentName, @Nullable String nonLocalizedLabel, @Nullable Integer icon, int userId) { @@ -5758,25 +3860,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public void setComponentEnabledSetting(ComponentName componentName, - int newState, int flags, int userId) { - if (!mUserManager.exists(userId)) return; - - setEnabledSettings(List.of(new ComponentEnabledSetting(componentName, newState, flags)), - userId, null /* callingPackage */); - } - - @Override - public void setComponentEnabledSettings(List settings, int userId) { - if (!mUserManager.exists(userId)) return; - if (settings == null || settings.isEmpty()) { - throw new IllegalArgumentException("The list of enabled settings is empty"); - } - - setEnabledSettings(settings, userId, null /* callingPackage */); - } - private void setEnabledSettings(List settings, int userId, String callingPackage) { final int callingUid = Binder.getCallingUid(); @@ -5846,7 +3929,7 @@ public class PackageManagerService extends IPackageManager.Stub continue; } final boolean isCallerTargetApp = ArrayUtils.contains( - getPackagesForUid(callingUid), packageName); + mIPackageManager.getPackagesForUid(callingUid), packageName); final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName); // Limit who can change which apps if (!isCallerTargetApp) { @@ -6054,8 +4137,8 @@ public class PackageManagerService extends IPackageManager.Stub pkgSetting.setEnabled(newState, userId, callingPackage); if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER || newState == COMPONENT_ENABLED_STATE_DISABLED) - && checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId) - == PERMISSION_GRANTED) { + && mIPackageManager.checkPermission(Manifest.permission.SUSPEND_APPS, + packageName, userId) == PERMISSION_GRANTED) { // This app should not generally be allowed to get disabled by the UI, but // if it ever does, we don't want to end up with some of the user's apps // permanently suspended. @@ -6098,22 +4181,6 @@ public class PackageManagerService extends IPackageManager.Stub return true; } - @WorkerThread - @Override - public void flushPackageRestrictionsAsUser(int userId) { - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { - return; - } - if (!mUserManager.exists(userId)) { - return; - } - enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, - false /* checkShell */, "flushPackageRestrictions"); - synchronized (mLock) { - flushPackageRestrictionsAsUserInternalLocked(userId); - } - } - @GuardedBy("mLock") private void flushPackageRestrictionsAsUserInternalLocked(int userId) { // NOTE: this invokes synchronous disk access, so callers using this @@ -6146,100 +4213,17 @@ public class PackageManagerService extends IPackageManager.Stub return mComputer.getBroadcastAllowList(packageName, userIds, isInstantApp); } - @Override - public void setPackageStoppedState(String packageName, boolean stopped, int userId) { - if (!mUserManager.exists(userId)) return; - final int callingUid = Binder.getCallingUid(); - final Computer computer = snapshotComputer(); - if (computer.getInstantAppPackageName(callingUid) == null) { - final int permission = mContext.checkCallingOrSelfPermission( - android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); - final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); - if (!allowedByPermission - && !ArrayUtils.contains(computer.getPackagesForUid(callingUid), packageName)) { - throw new SecurityException( - "Permission Denial: attempt to change stopped state from pid=" - + Binder.getCallingPid() - + ", uid=" + callingUid + ", package=" + packageName); - } - computer.enforceCrossUserPermission(callingUid, userId, - true /* requireFullPermission */, true /* checkShell */, "stop package"); - - final PackageStateInternal packageState = computer.getPackageStateInternal(packageName); - final PackageUserState packageUserState = packageState == null - ? null : packageState.getUserStateOrDefault(userId); - if (packageState != null - && !computer.shouldFilterApplication(packageState, callingUid, userId) - && packageUserState.isStopped() != stopped) { - boolean wasNotLaunched = packageUserState.isNotLaunched(); - commitPackageStateMutation(null, packageName, state -> { - PackageUserStateWrite userState = state.userState(userId); - userState.setStopped(stopped); - if (wasNotLaunched) { - userState.setNotLaunched(false); - } - }); - - if (wasNotLaunched) { - final String installerPackageName = - packageState.getInstallSource().installerPackageName; - if (installerPackageName != null) { - notifyFirstLaunch(packageName, installerPackageName, userId); - } - } - - scheduleWritePackageRestrictions(userId); - } - } - - // If this would cause the app to leave force-stop, then also make sure to unhibernate the - // app if needed. - if (!stopped) { - mHandler.post(() -> { - AppHibernationManagerInternal ah = - mInjector.getLocalService(AppHibernationManagerInternal.class); - if (ah != null && ah.isHibernatingForUser(packageName, userId)) { - ah.setHibernatingForUser(packageName, userId, false); - ah.setHibernatingGlobally(packageName, false); - } - }); + /** + * Used by SystemServer + */ + public void waitForAppDataPrepared() { + if (mPrepareAppDataFuture == null) { + return; } + ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData"); + mPrepareAppDataFuture = null; } - @Nullable - @Override - public String getInstallerPackageName(@NonNull String packageName) { - return mComputer.getInstallerPackageName(packageName); - } - - @Override - @Nullable - public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) { - return mComputer.getInstallSourceInfo(packageName); - } - - @PackageManager.EnabledState - @Override - public int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId) { - return mComputer.getApplicationEnabledSetting(packageName, userId); - } - - @Override - public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) { - return mComputer.getComponentEnabledSetting(component, Binder.getCallingUid(), userId); - } - - @Override - public void enterSafeMode() { - PackageManagerServiceUtils.enforceSystemOrRoot( - "Only the system can request entering safe mode"); - - if (!mSystemReady) { - mSafeMode = true; - } - } - - @Override public void systemReady() { PackageManagerServiceUtils.enforceSystemOrRoot( "Only the system can claim the system is ready"); @@ -6270,7 +4254,7 @@ public class PackageManagerService extends IPackageManager.Stub .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE), false, co, UserHandle.USER_ALL); mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure - .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL); + .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL); co.onChange(true); mAppsFilter.onSystemReady(); @@ -6409,44 +4393,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - /** - * Used by SystemServer - */ - public void waitForAppDataPrepared() { - if (mPrepareAppDataFuture == null) { - return; - } - ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData"); - mPrepareAppDataFuture = null; - } - - @Override - public boolean isSafeMode() { - // allow instant applications - return mSafeMode; - } - - @Override - public boolean hasSystemUidErrors() { - // allow instant applications - return false; - } - - @Override - public void onShellCommand(FileDescriptor in, FileDescriptor out, - FileDescriptor err, String[] args, ShellCallback callback, - ResultReceiver resultReceiver) { - (new PackageManagerShellCommand(this, mContext,mDomainVerificationManager.getShell())) - .exec(this, in, out, err, args, callback, resultReceiver); - } - - @SuppressWarnings("resource") - @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; - new DumpHelper(this).doDump(fd, pw, args); - } - void dumpSnapshotStats(PrintWriter pw, boolean isBrief) { if (mSnapshotStatistics == null) { return; @@ -6483,9 +4429,9 @@ public class PackageManagerService extends IPackageManager.Stub return; } for (String packageName : apkList) { - setSystemAppHiddenUntilInstalled(packageName, true); + mIPackageManager.setSystemAppHiddenUntilInstalled(packageName, true); for (UserInfo user : mInjector.getUserManagerInternal().getUsers(false)) { - setSystemAppInstallState(packageName, false, user.id); + mIPackageManager.setSystemAppInstallState(packageName, false, user.id); } } } @@ -6523,98 +4469,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public int movePackage(final String packageName, final String volumeUuid) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); - - final int callingUid = Binder.getCallingUid(); - final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid)); - final int moveId = mNextMoveId.getAndIncrement(); - mHandler.post(() -> { - try { - MovePackageHelper movePackageHelper = new MovePackageHelper(this); - movePackageHelper.movePackageInternal( - packageName, volumeUuid, moveId, callingUid, user); - } catch (PackageManagerException e) { - Slog.w(TAG, "Failed to move " + packageName, e); - mMoveCallbacks.notifyStatusChanged(moveId, e.error); - } - }); - return moveId; - } - - @Override - public int movePrimaryStorage(String volumeUuid) throws RemoteException { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); - - final int realMoveId = mNextMoveId.getAndIncrement(); - final Bundle extras = new Bundle(); - extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); - mMoveCallbacks.notifyCreated(realMoveId, extras); - - final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { - @Override - public void onCreated(int moveId, Bundle extras) { - // Ignored - } - - @Override - public void onStatusChanged(int moveId, int status, long estMillis) { - mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); - } - }; - - final StorageManager storage = mInjector.getSystemService(StorageManager.class); - storage.setPrimaryStorageUuid(volumeUuid, callback); - return realMoveId; - } - - @Override - public int getMoveStatus(int moveId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); - return mMoveCallbacks.mLastStatus.get(moveId); - } - - @Override - public void registerMoveCallback(IPackageMoveObserver callback) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); - mMoveCallbacks.register(callback); - } - - @Override - public void unregisterMoveCallback(IPackageMoveObserver callback) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); - mMoveCallbacks.unregister(callback); - } - - @Override - public boolean setInstallLocation(int loc) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, - null); - if (getInstallLocation() == loc) { - return true; - } - if (loc == InstallLocationUtils.APP_INSTALL_AUTO - || loc == InstallLocationUtils.APP_INSTALL_INTERNAL - || loc == InstallLocationUtils.APP_INSTALL_EXTERNAL) { - android.provider.Settings.Global.putInt(mContext.getContentResolver(), - android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); - return true; - } - return false; - } - - @Override - public int getInstallLocation() { - // allow instant app access - return android.provider.Settings.Global.getInt(mContext.getContentResolver(), - android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, - InstallLocationUtils.APP_INSTALL_AUTO); - } - /** Called by UserManagerService */ void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) { synchronized (mLock) { @@ -6674,18 +4528,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, - "Only package verification agents can read the verifier device identity"); - - synchronized (mLock) { - return mSettings.getVerifierDeviceIdentityLPw(mLiveComputer); - } - } - - @Override public boolean isStorageLow() { // allow instant applications final long token = Binder.clearCallingIdentity(); @@ -6702,50 +4544,10 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public IPackageInstaller getPackageInstaller() { - // Return installer service for internal calls. - if (PackageManagerServiceUtils.isSystemOrRoot()) { - return mInstallerService; - } - // Return null for InstantApps. - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { - return null; - } - return mInstallerService; - } - - @Override - public IArtManager getArtManager() { - return mArtManagerService; - } - boolean userNeedsBadging(int userId) { return mUserNeedsBadging.get(userId); } - @Nullable - @Override - public KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) { - return mComputer.getKeySetByAlias(packageName, alias); - } - - @Nullable - @Override - public KeySet getSigningKeySet(@NonNull String packageName) { - return mComputer.getSigningKeySet(packageName); - } - - @Override - public boolean isPackageSignedByKeySet(@NonNull String packageName, @NonNull KeySet ks) { - return mComputer.isPackageSignedByKeySet(packageName, ks); - } - - @Override - public boolean isPackageSignedByKeySetExactly(@NonNull String packageName, @NonNull KeySet ks) { - return mComputer.isPackageSignedByKeySetExactly(packageName, ks); - } - private void deletePackageIfUnused(final String packageName) { PackageStateInternal ps = getPackageStateInternal(packageName); if (ps == null) { @@ -6802,6 +4604,2512 @@ public class PackageManagerService extends IPackageManager.Stub return mComputer.canQueryPackage(callingUid, targetPackageName); } + void checkPackageStartable(@NonNull Computer snapshot, @NonNull String packageName, + @UserIdInt int userId) { + final int callingUid = Binder.getCallingUid(); + if (snapshot.getInstantAppPackageName(callingUid) != null) { + throw new SecurityException("Instant applications don't have access to this method"); + } + if (!mUserManager.exists(userId)) { + throw new SecurityException("User doesn't exist"); + } + snapshot.enforceCrossUserPermission(callingUid, userId, false, false, + "checkPackageStartable"); + switch (snapshot.getPackageStartability(mSafeMode, packageName, callingUid, userId)) { + case PACKAGE_STARTABILITY_NOT_FOUND: + throw new SecurityException("Package " + packageName + " was not found!"); + case PACKAGE_STARTABILITY_NOT_SYSTEM: + throw new SecurityException("Package " + packageName + " not a system app!"); + case PACKAGE_STARTABILITY_FROZEN: + throw new SecurityException("Package " + packageName + " is currently frozen!"); + case PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED: + throw new SecurityException("Package " + packageName + " is not encryption aware!"); + case PACKAGE_STARTABILITY_OK: + default: + } + } + + void setPackageStoppedState(@NonNull Computer snapshot, @NonNull String packageName, + boolean stopped, @UserIdInt int userId) { + if (!mUserManager.exists(userId)) return; + final int callingUid = Binder.getCallingUid(); + if (snapshot.getInstantAppPackageName(callingUid) == null) { + final int permission = mContext.checkCallingOrSelfPermission( + Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); + final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); + if (!allowedByPermission + && !ArrayUtils.contains(snapshot.getPackagesForUid(callingUid), packageName)) { + throw new SecurityException( + "Permission Denial: attempt to change stopped state from pid=" + + Binder.getCallingPid() + + ", uid=" + callingUid + ", package=" + packageName); + } + snapshot.enforceCrossUserPermission(callingUid, userId, + true /* requireFullPermission */, true /* checkShell */, "stop package"); + + final PackageStateInternal packageState = + snapshot.getPackageStateInternal(packageName); + final PackageUserState packageUserState = packageState == null + ? null : packageState.getUserStateOrDefault(userId); + if (packageState != null + && !snapshot.shouldFilterApplication(packageState, callingUid, userId) + && packageUserState.isStopped() != stopped) { + boolean wasNotLaunched = packageUserState.isNotLaunched(); + commitPackageStateMutation(null, packageName, state -> { + PackageUserStateWrite userState = state.userState(userId); + userState.setStopped(stopped); + if (wasNotLaunched) { + userState.setNotLaunched(false); + } + }); + + if (wasNotLaunched) { + final String installerPackageName = + packageState.getInstallSource().installerPackageName; + if (installerPackageName != null) { + notifyFirstLaunch(packageName, installerPackageName, userId); + } + } + + scheduleWritePackageRestrictions(userId); + } + } + + // If this would cause the app to leave force-stop, then also make sure to unhibernate the + // app if needed. + if (!stopped) { + mHandler.post(() -> { + AppHibernationManagerInternal ah = + mInjector.getLocalService(AppHibernationManagerInternal.class); + if (ah != null && ah.isHibernatingForUser(packageName, userId)) { + ah.setHibernatingForUser(packageName, userId, false); + ah.setHibernatingGlobally(packageName, false); + } + }); + } + } + + public class IPackageManagerImpl extends IPackageManager.Stub { + + @Override + public boolean activitySupportsIntent(ComponentName component, Intent intent, + String resolvedType) { + return mComputer.activitySupportsIntent(mResolveComponentName, component, intent, + resolvedType); + } + + @Override + public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, + int sourceUserId, int targetUserId, int flags) { + PackageManagerService.this.addCrossProfileIntentFilter( + new WatchedIntentFilter(intentFilter), ownerPackage, sourceUserId, targetUserId, + flags); + } + + // NOTE: Can't remove due to unsupported app usage + @Override + public boolean addPermission(PermissionInfo info) { + // Because this is accessed via the package manager service AIDL, + // go through the permission manager service AIDL + return mContext.getSystemService(PermissionManager.class).addPermission(info, false); + } + + // NOTE: Can't remove due to unsupported app usage + @Override + public boolean addPermissionAsync(PermissionInfo info) { + // Because this is accessed via the package manager service AIDL, + // go through the permission manager service AIDL + return mContext.getSystemService(PermissionManager.class).addPermission(info, true); + } + + @Override + public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, + int userId) { + mPreferredActivityHelper.addPersistentPreferredActivity(new WatchedIntentFilter(filter), + activity, userId); + } + + @Override + public void addPreferredActivity(IntentFilter filter, int match, + ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) { + mPreferredActivityHelper.addPreferredActivity(new WatchedIntentFilter(filter), match, + set, activity, true, userId, "Adding preferred", removeExisting); + } + + /* + * Returns if intent can be forwarded from the sourceUserId to the targetUserId + */ + @Override + public boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType, + @UserIdInt int sourceUserId, @UserIdInt int targetUserId) { + return mComputer.canForwardTo(intent, resolvedType, sourceUserId, targetUserId); + } + + @Override + public boolean canRequestPackageInstalls(String packageName, int userId) { + return mComputer.canRequestPackageInstalls(packageName, Binder.getCallingUid(), userId, + true /* throwIfPermNotDeclared*/); + } + + @Override + public String[] canonicalToCurrentPackageNames(String[] names) { + return mComputer.canonicalToCurrentPackageNames(names); + } + + @Override + public void checkPackageStartable(String packageName, int userId) { + PackageManagerService.this + .checkPackageStartable(snapshotComputer(), packageName, userId); + } + + // NOTE: Can't remove due to unsupported app usage + @Override + public int checkPermission(String permName, String pkgName, int userId) { + return PackageManagerService.this.checkPermission(permName, pkgName, userId); + } + + @Override + public int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) { + return mComputer.checkSignatures(pkg1, pkg2); + } + + @Override + public int checkUidPermission(String permName, int uid) { + return mComputer.checkUidPermission(permName, uid); + } + + @Override + public int checkUidSignatures(int uid1, int uid2) { + return mComputer.checkUidSignatures(uid1, uid2); + } + + @Override + public void clearApplicationProfileData(String packageName) { + PackageManagerServiceUtils.enforceSystemOrRoot( + "Only the system can clear all profile data"); + + final AndroidPackage pkg = getPackage(packageName); + try (PackageFreezer ignored = freezePackage(packageName, "clearApplicationProfileData")) { + synchronized (mInstallLock) { + mAppDataHelper.clearAppProfilesLIF(pkg); + } + } + } + + @Override + public void clearApplicationUserData(final String packageName, + final IPackageDataObserver observer, final int userId) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CLEAR_APP_USER_DATA, null); + + final int callingUid = Binder.getCallingUid(); + enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */, + false /* checkShell */, "clear application data"); + + if (mComputer.getPackageStateFiltered(packageName, callingUid, userId) == null) { + if (observer != null) { + mHandler.post(() -> { + try { + observer.onRemoveCompleted(packageName, false); + } catch (RemoteException e) { + Log.i(TAG, "Observer no longer exists."); + } + }); + } + return; + } + if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { + throw new SecurityException("Cannot clear data for a protected package: " + + packageName); + } + + // Queue up an async operation since the package deletion may take a little while. + mHandler.post(new Runnable() { + public void run() { + mHandler.removeCallbacks(this); + final boolean succeeded; + try (PackageFreezer freezer = freezePackage(packageName, + "clearApplicationUserData")) { + synchronized (mInstallLock) { + succeeded = clearApplicationUserDataLIF(packageName, userId); + } + mInstantAppRegistry.deleteInstantApplicationMetadata(packageName, userId); + synchronized (mLock) { + if (succeeded) { + resetComponentEnabledSettingsIfNeededLPw(packageName, userId); + } + } + } + if (succeeded) { + // invoke DeviceStorageMonitor's update method to clear any notifications + DeviceStorageMonitorInternal dsm = LocalServices + .getService(DeviceStorageMonitorInternal.class); + if (dsm != null) { + dsm.checkMemory(); + } + if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId) + == PERMISSION_GRANTED) { + unsuspendForSuspendingPackage(snapshotComputer(), packageName, userId); + removeAllDistractingPackageRestrictions(userId); + flushPackageRestrictionsAsUserInternalLocked(userId); + } + } + if (observer != null) { + try { + observer.onRemoveCompleted(packageName, succeeded); + } catch (RemoteException e) { + Log.i(TAG, "Observer no longer exists."); + } + } //end if observer + } //end run + }); + } + + @Override + public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); + final int callingUid = Binder.getCallingUid(); + enforceOwnerRights(ownerPackage, callingUid); + PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(), + UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); + synchronized (mLock) { + CrossProfileIntentResolver resolver = + mSettings.editCrossProfileIntentResolverLPw(sourceUserId); + ArraySet set = + new ArraySet<>(resolver.filterSet()); + for (CrossProfileIntentFilter filter : set) { + if (filter.getOwnerPackage().equals(ownerPackage)) { + resolver.removeFilter(filter); + } + } + } + scheduleWritePackageRestrictions(sourceUserId); + } + + @Override + public void clearPackagePersistentPreferredActivities(String packageName, int userId) { + mPreferredActivityHelper.clearPackagePersistentPreferredActivities(packageName, userId); + } + + @Override + public void clearPackagePreferredActivities(String packageName) { + mPreferredActivityHelper.clearPackagePreferredActivities(packageName); + } + + @Override + public String[] currentToCanonicalPackageNames(String[] names) { + return mComputer.currentToCanonicalPackageNames(names); + } + + @Override + public void deleteApplicationCacheFiles(final String packageName, + final IPackageDataObserver observer) { + final int userId = UserHandle.getCallingUserId(); + deleteApplicationCacheFilesAsUser(packageName, userId, observer); + } + + @Override + public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, + final IPackageDataObserver observer) { + final int callingUid = Binder.getCallingUid(); + if (mContext.checkCallingOrSelfPermission( + android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES) + != PackageManager.PERMISSION_GRANTED) { + // If the caller has the old delete cache permission, silently ignore. Else throw. + if (mContext.checkCallingOrSelfPermission( + android.Manifest.permission.DELETE_CACHE_FILES) + == PackageManager.PERMISSION_GRANTED) { + Slog.w(TAG, "Calling uid " + callingUid + " does not have " + + android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES + + ", silently ignoring"); + return; + } + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null); + } + enforceCrossUserPermission(callingUid, userId, /* requireFullPermission= */ true, + /* checkShell= */ false, "delete application cache files"); + final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission( + android.Manifest.permission.ACCESS_INSTANT_APPS); + + final AndroidPackage pkg = getPackage(packageName); + + // Queue up an async operation since the package deletion may take a little while. + mHandler.post(() -> { + final PackageStateInternal ps = + pkg == null ? null : getPackageStateInternal(pkg.getPackageName()); + boolean doClearData = true; + if (ps != null) { + final boolean targetIsInstantApp = + ps.getUserStateOrDefault(UserHandle.getUserId(callingUid)).isInstantApp(); + doClearData = !targetIsInstantApp + || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED; + } + if (doClearData) { + synchronized (mInstallLock) { + final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL; + // We're only clearing cache files, so we don't care if the + // app is unfrozen and still able to run + mAppDataHelper.clearAppDataLIF(pkg, userId, + flags | Installer.FLAG_CLEAR_CACHE_ONLY); + mAppDataHelper.clearAppDataLIF(pkg, userId, + flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); + } + } + if (observer != null) { + try { + observer.onRemoveCompleted(packageName, true); + } catch (RemoteException e) { + Log.i(TAG, "Observer no longer exists."); + } + } + }); + } + + @Override + public void deleteExistingPackageAsUser(VersionedPackage versionedPackage, + final IPackageDeleteObserver2 observer, final int userId) { + PackageManagerService.this.deleteExistingPackageAsUser(versionedPackage, observer, + userId); + } + + @Override + public void deletePackageAsUser(String packageName, int versionCode, + IPackageDeleteObserver observer, int userId, int flags) { + deletePackageVersioned(new VersionedPackage(packageName, versionCode), + new PackageManager.LegacyPackageDeleteObserver(observer).getBinder(), userId, flags); + } + + @Override + public void deletePackageVersioned(VersionedPackage versionedPackage, + final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { + PackageManagerService.this.deletePackageVersioned(versionedPackage, observer, + userId, deleteFlags); + } + + @Override + public void deletePreloadsFileCache() { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE, + "deletePreloadsFileCache"); + File dir = Environment.getDataPreloadsFileCacheDirectory(); + Slog.i(PackageManagerService.TAG, "Deleting preloaded file cache " + dir); + FileUtils.deleteContents(dir); + } + + @Override + public void dumpProfiles(String packageName) { + /* Only the shell, root, or the app user should be able to dump profiles. */ + final int callingUid = Binder.getCallingUid(); + final String[] callerPackageNames = getPackagesForUid(callingUid); + if (callingUid != Process.SHELL_UID + && callingUid != Process.ROOT_UID + && !ArrayUtils.contains(callerPackageNames, packageName)) { + throw new SecurityException("dumpProfiles"); + } + + AndroidPackage pkg = mComputer.getPackage(packageName); + if (pkg == null) { + throw new IllegalArgumentException("Unknown package: " + packageName); + } + + synchronized (mInstallLock) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); + mArtManagerService.dumpProfiles(pkg); + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + } + + @Override + public void enterSafeMode() { + PackageManagerServiceUtils.enforceSystemOrRoot( + "Only the system can request entering safe mode"); + + if (!mSystemReady) { + mSafeMode = true; + } + } + + @Override + public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, + long millisecondsToDelay) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.PACKAGE_VERIFICATION_AGENT, + "Only package verification agents can extend verification timeouts"); + final int callingUid = Binder.getCallingUid(); + + mHandler.post(() -> { + final PackageVerificationState state = mPendingVerification.get(id); + final PackageVerificationResponse response = new PackageVerificationResponse( + verificationCodeAtTimeout, callingUid); + + long delay = millisecondsToDelay; + if (delay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { + delay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; + } + if (delay < 0) { + delay = 0; + } + + if ((state != null) && !state.timeoutExtended()) { + state.extendTimeout(); + + final Message msg = mHandler.obtainMessage(PackageManagerService.PACKAGE_VERIFIED); + msg.arg1 = id; + msg.obj = response; + mHandler.sendMessageDelayed(msg, delay); + } + }); + } + + @Override + public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) { + return mPreferredActivityHelper.findPersistentPreferredActivity(intent, userId); + } + + @Override + public void finishPackageInstall(int token, boolean didLaunch) { + PackageManagerServiceUtils.enforceSystemOrRoot( + "Only the system is allowed to finish installs"); + + if (PackageManagerService.DEBUG_INSTALL) { + Slog.v(PackageManagerService.TAG, "BM finishing package install for " + token); + } + Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); + + final Message msg = mHandler.obtainMessage(PackageManagerService.POST_INSTALL, token, didLaunch ? 1 : 0); + mHandler.sendMessage(msg); + } + + @WorkerThread + @Override + public void flushPackageRestrictionsAsUser(int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return; + } + if (!mUserManager.exists(userId)) { + return; + } + enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, + false /* checkShell */, "flushPackageRestrictions"); + synchronized (mLock) { + flushPackageRestrictionsAsUserInternalLocked(userId); + } + } + + @Override + public void forceDexOpt(String packageName) { + mDexOptHelper.forceDexOpt(packageName); + } + + + @Override + public void freeStorage(final String volumeUuid, final long freeStorageSize, + final @StorageManager.AllocateFlags int flags, final IntentSender pi) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CLEAR_APP_CACHE, TAG); + mHandler.post(() -> { + boolean success = false; + try { + PackageManagerService.this.freeStorage(volumeUuid, freeStorageSize, flags); + success = true; + } catch (IOException e) { + Slog.w(TAG, e); + } + if (pi != null) { + try { + pi.sendIntent(null, success ? 1 : 0, null, null, null); + } catch (SendIntentException e) { + Slog.w(TAG, e); + } + } + }); + } + + @Override + public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, + final @StorageManager.AllocateFlags int flags, final IPackageDataObserver observer) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CLEAR_APP_CACHE, null); + mHandler.post(() -> { + boolean success = false; + try { + PackageManagerService.this.freeStorage(volumeUuid, freeStorageSize, flags); + success = true; + } catch (IOException e) { + Slog.w(PackageManagerService.TAG, e); + } + if (observer != null) { + try { + observer.onRemoveCompleted(null, success); + } catch (RemoteException e) { + Slog.w(PackageManagerService.TAG, e); + } + } + }); + } + + @Override + public ActivityInfo getActivityInfo(ComponentName component, + @PackageManager.ComponentInfoFlagsBits long flags, int userId) { + return mComputer.getActivityInfo(component, flags, userId); + } + + @NonNull + @Override + public ParceledListSlice getAllIntentFilters(@NonNull String packageName) { + return mComputer.getAllIntentFilters(packageName); + } + + @Override + public List getAllPackages() { + return mComputer.getAllPackages(); + } + + // NOTE: Can't remove due to unsupported app usage + @NonNull + @Override + public String[] getAppOpPermissionPackages(@NonNull String permissionName) { + return mComputer.getAppOpPermissionPackages(permissionName); + } + + @Override + public String getAppPredictionServicePackageName() { + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_defaultAppPredictionService)); + } + + @PackageManager.EnabledState + @Override + public int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId) { + return mComputer.getApplicationEnabledSetting(packageName, userId); + } + + /** + * Returns true if application is not found or there was an error. Otherwise it returns + * the hidden state of the package for the given user. + */ + @Override + public boolean getApplicationHiddenSettingAsUser(@NonNull String packageName, + @UserIdInt int userId) { + return mComputer.getApplicationHiddenSettingAsUser(packageName, userId); + } + + @Override + public ApplicationInfo getApplicationInfo(String packageName, + @PackageManager.ApplicationInfoFlagsBits long flags, int userId) { + return mComputer.getApplicationInfo(packageName, flags, userId); + } + + @Override + public IArtManager getArtManager() { + return mArtManagerService; + } + + @Override + public @Nullable String getAttentionServicePackageName() { + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_defaultAttentionService)); + } + + @Override + public boolean getBlockUninstallForUser(@NonNull String packageName, @UserIdInt int userId) { + return mComputer.getBlockUninstallForUser(packageName, userId); + } + + @Override + public ChangedPackages getChangedPackages(int sequenceNumber, int userId) { + final int callingUid = Binder.getCallingUid(); + if (getInstantAppPackageName(callingUid) != null) { + return null; + } + if (!mUserManager.exists(userId)) { + return null; + } + enforceCrossUserPermission(callingUid, userId, false, false, "getChangedPackages"); + final ChangedPackages changedPackages = mChangedPackagesTracker.getChangedPackages( + sequenceNumber, userId); + + if (changedPackages != null) { + final List packageNames = changedPackages.getPackageNames(); + for (int index = packageNames.size() - 1; index >= 0; index--) { + // Filter out the changes if the calling package should not be able to see it. + final PackageSetting ps = mSettings.getPackageLPr(packageNames.get(index)); + if (shouldFilterApplication(ps, callingUid, userId)) { + packageNames.remove(index); + } + } + } + + return changedPackages; + } + + @Override + public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) { + return mComputer.getComponentEnabledSetting(component, Binder.getCallingUid(), userId); + } + + @Override + public String getContentCaptureServicePackageName() { + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_defaultContentCaptureService)); + } + + @Nullable + @Override + public ParceledListSlice getDeclaredSharedLibraries( + @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags, + @NonNull int userId) { + return mComputer.getDeclaredSharedLibraries(packageName, flags, userId); + } + + /** + * Non-Binder method, support for the backup/restore mechanism: write the + * default browser (etc) settings in its canonical XML format. Returns the default + * browser XML representation as a byte array, or null if there is none. + */ + @Override + public byte[] getDefaultAppsBackup(int userId) { + return mPreferredActivityHelper.getDefaultAppsBackup(userId); + } + + @Override + public String getDefaultTextClassifierPackageName() { + return ensureSystemPackageName( + mContext.getString(R.string.config_servicesExtensionPackage)); + } + + @Override + public byte[] getDomainVerificationBackup(int userId) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Only the system may call getDomainVerificationBackup()"); + } + + try { + try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { + TypedXmlSerializer serializer = Xml.resolveSerializer(output); + mDomainVerificationManager.writeSettings(snapshotComputer(), serializer, true, + userId); + return output.toByteArray(); + } + } catch (Exception e) { + if (PackageManagerService.DEBUG_BACKUP) { + Slog.e(PackageManagerService.TAG, "Unable to write domain verification for backup", e); + } + return null; + } + } + + @Override + public int getFlagsForUid(int uid) { + return mComputer.getFlagsForUid(uid); + } + + @Nullable + @Override + public CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId) { + return mComputer.getHarmfulAppWarning(packageName, userId); + } + + @Override + public IBinder getHoldLockToken() { + if (!Build.IS_DEBUGGABLE) { + throw new SecurityException("getHoldLockToken requires a debuggable build"); + } + + mContext.enforceCallingPermission( + Manifest.permission.INJECT_EVENTS, + "getHoldLockToken requires INJECT_EVENTS permission"); + + final Binder token = new Binder(); + token.attachInterface(this, "holdLock:" + Binder.getCallingUid()); + return token; + } + + @Override + public ComponentName getHomeActivities(List allHomeCandidates) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } + return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); + } + + public String getIncidentReportApproverPackageName() { + return ensureSystemPackageName(mContext.getString( + R.string.config_incidentReportApproverPackage)); + } + + @Override + public int getInstallLocation() { + // allow instant app access + return android.provider.Settings.Global.getInt(mContext.getContentResolver(), + android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, + InstallLocationUtils.APP_INSTALL_AUTO); + } + + @PackageManager.InstallReason + @Override + public int getInstallReason(@NonNull String packageName, @UserIdInt int userId) { + return mComputer.getInstallReason(packageName, userId); + } + + @Override + @Nullable + public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) { + return mComputer.getInstallSourceInfo(packageName); + } + + @Override + public ParceledListSlice getInstalledApplications( + @PackageManager.ApplicationInfoFlagsBits long flags, int userId) { + final int callingUid = Binder.getCallingUid(); + return new ParceledListSlice<>( + mComputer.getInstalledApplications(flags, userId, callingUid)); + } + + @Override + public List getInstalledModules(int flags) { + return mModuleInfoProvider.getInstalledModules(flags); + } + + @Override + public ParceledListSlice getInstalledPackages( + @PackageManager.PackageInfoFlagsBits long flags, int userId) { + return mComputer.getInstalledPackages(flags, userId); + } + + @Nullable + @Override + public String getInstallerPackageName(@NonNull String packageName) { + return mComputer.getInstallerPackageName(packageName); + } + + @Override + public String getInstantAppAndroidId(String packageName, int userId) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS, + "getInstantAppAndroidId"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, + "getInstantAppAndroidId"); + // Make sure the target is an Instant App. + if (!isInstantApp(packageName, userId)) { + return null; + } + return mInstantAppRegistry.getInstantAppAndroidId(packageName, userId); + } + + @Override + public byte[] getInstantAppCookie(String packageName, int userId) { + if (HIDE_EPHEMERAL_APIS) { + return null; + } + + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, + "getInstantAppCookie"); + if (!isCallerSameApp(packageName, Binder.getCallingUid())) { + return null; + } + PackageStateInternal packageState = getPackageStateInternal(packageName); + if (packageState == null || packageState.getPkg() == null) { + return null; + } + return mInstantAppRegistry.getInstantAppCookie(packageState.getPkg(), userId); + } + + @Override + public Bitmap getInstantAppIcon(String packageName, int userId) { + if (HIDE_EPHEMERAL_APIS) { + return null; + } + + if (!canViewInstantApps(Binder.getCallingUid(), userId)) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, + "getInstantAppIcon"); + } + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, + "getInstantAppIcon"); + + return mInstantAppRegistry.getInstantAppIcon(packageName, userId); + } + + @Override + public ComponentName getInstantAppInstallerComponent() { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } + return mInstantAppInstallerActivity == null + ? null : mInstantAppInstallerActivity.getComponentName(); + } + + @Override + public @Nullable ComponentName getInstantAppResolverComponent() { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } + return getInstantAppResolver(); + } + + @Override + public ComponentName getInstantAppResolverSettingsComponent() { + return mInstantAppResolverSettingsComponent; + } + + @Override + public ParceledListSlice getInstantApps(int userId) { + if (PackageManagerService.HIDE_EPHEMERAL_APIS) { + return null; + } + if (!canViewInstantApps(Binder.getCallingUid(), userId)) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, + "getEphemeralApplications"); + } + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, + "getEphemeralApplications"); + + Computer computer = snapshotComputer(); + List instantApps = mInstantAppRegistry.getInstantApps(computer, userId); + if (instantApps != null) { + return new ParceledListSlice<>(instantApps); + } + return null; + } + + @Nullable + @Override + public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) { + return mComputer.getInstrumentationInfo(component, flags); + } + + @Deprecated + @Override + public @NonNull ParceledListSlice getIntentFilterVerifications( + String packageName) { + return ParceledListSlice.emptyList(); + } + + @Deprecated + @Override + public int getIntentVerificationStatus(String packageName, int userId) { + return mDomainVerificationManager.getLegacyState(packageName, userId); + } + + @Nullable + @Override + public KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) { + return mComputer.getKeySetByAlias(packageName, alias); + } + + @Override + public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { + return mPreferredActivityHelper.getLastChosenActivity(intent, resolvedType, flags); + } + + @Override + public IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage, + String featureId, int userId) throws RemoteException { + return mResolveIntentHelper.getLaunchIntentSenderForPackage(snapshotComputer(), + packageName, callingPackage, featureId, userId); + } + + @Override + public List getMimeGroup(String packageName, String mimeGroup) { + enforceOwnerRights(packageName, Binder.getCallingUid()); + return getMimeGroupInternal(packageName, mimeGroup); + } + + @Override + public ModuleInfo getModuleInfo(String packageName, @PackageManager.ModuleInfoFlags int flags) { + return PackageManagerService.this.getModuleInfo(packageName, flags); + } + + @Override + public int getMoveStatus(int moveId) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); + return mMoveCallbacks.mLastStatus.get(moveId); + } + + @Nullable + @Override + public String getNameForUid(int uid) { + return mComputer.getNameForUid(uid); + } + + @Nullable + @Override + public String[] getNamesForUids(@NonNull int[] uids) { + return mComputer.getNamesForUids(uids); + } + + @Override + public int[] getPackageGids(String packageName, @PackageManager.PackageInfoFlagsBits long flags, + int userId) { + return mComputer.getPackageGids(packageName, flags, userId); + } + + @Override + public PackageInfo getPackageInfo(String packageName, + @PackageManager.PackageInfoFlagsBits long flags, int userId) { + return mComputer.getPackageInfo(packageName, flags, userId); + } + + @Override + public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage, + @PackageManager.PackageInfoFlagsBits long flags, int userId) { + return mComputer.getPackageInfoInternal(versionedPackage.getPackageName(), + versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId); + } + + @Override + public IPackageInstaller getPackageInstaller() { + // Return installer service for internal calls. + if (PackageManagerServiceUtils.isSystemOrRoot()) { + return mInstallerService; + } + // Return null for InstantApps. + if (snapshotComputer().getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } + return mInstallerService; + } + + @Override + public void getPackageSizeInfo(final String packageName, int userId, + final IPackageStatsObserver observer) { + throw new UnsupportedOperationException( + "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!"); + } + + @Override + public int getPackageUid(@NonNull String packageName, + @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) { + return mComputer.getPackageUid(packageName, flags, userId); + } + + /** + * IMPORTANT: Not all packages returned by this method may be known + * to the system. There are two conditions in which this may occur: + *
    + *
  1. The package is on adoptable storage and the device has been removed
  2. + *
  3. The package is being removed and the internal structures are partially updated
  4. + *
+ * The second is an artifact of the current data structures and should be fixed. See + * b/111075456 for one such instance. + * This binder API is cached. If the algorithm in this method changes, + * or if the underlying objecs (as returned by getSettingLPr()) change + * then the logic that invalidates the cache must be revisited. See + * calls to invalidateGetPackagesForUidCache() to locate the points at + * which the cache is invalidated. + */ + @Override + public String[] getPackagesForUid(int uid) { + final int callingUid = Binder.getCallingUid(); + final int userId = UserHandle.getUserId(uid); + mComputer.enforceCrossUserOrProfilePermission(callingUid, userId, + /* requireFullPermission */ false, + /* checkShell */ false, "getPackagesForUid"); + return mComputer.getPackagesForUid(uid); + } + + @Override + public ParceledListSlice getPackagesHoldingPermissions( + @NonNull String[] permissions, @PackageManager.PackageInfoFlagsBits long flags, + @UserIdInt int userId) { + return mComputer.getPackagesHoldingPermissions(permissions, flags, userId); + } + + @Override + public String getPermissionControllerPackageName() { + final int callingUid = Binder.getCallingUid(); + if (mComputer.getPackageStateFiltered(mRequiredPermissionControllerPackage, + callingUid, UserHandle.getUserId(callingUid)) != null) { + return mRequiredPermissionControllerPackage; + } + + throw new IllegalStateException("PermissionController is not found"); + } + + // NOTE: Can't remove due to unsupported app usage + @Override + public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) { + return PackageManagerService.this.getPermissionGroupInfo(groupName, flags); + } + + @Override + public @NonNull ParceledListSlice getPersistentApplications(int flags) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return ParceledListSlice.emptyList(); + } + return new ParceledListSlice<>(mComputer.getPersistentApplications(mSafeMode, flags)); + } + + @Override + public int getPreferredActivities(List outFilters, + List outActivities, String packageName) { + return mPreferredActivityHelper.getPreferredActivities(outFilters, outActivities, + packageName, snapshotComputer()); + } + + /** + * Non-Binder method, support for the backup/restore mechanism: write the + * full set of preferred activities in its canonical XML format. Returns the + * XML output as a byte array, or null if there is none. + */ + @Override + public byte[] getPreferredActivityBackup(int userId) { + return mPreferredActivityHelper.getPreferredActivityBackup(userId); + } + + @Override + public int getPrivateFlagsForUid(int uid) { + return mComputer.getPrivateFlagsForUid(uid); + } + + @Override + public PackageManager.Property getProperty(String propertyName, String packageName, String className) { + Objects.requireNonNull(propertyName); + Objects.requireNonNull(packageName); + PackageStateInternal packageState = mComputer.getPackageStateFiltered(packageName, + Binder.getCallingUid(), UserHandle.getCallingUserId()); + if (packageState == null) { + return null; + } + return mPackageProperty.getProperty(propertyName, packageName, className); + } + + @Nullable + @Override + public ProviderInfo getProviderInfo(@NonNull ComponentName component, + @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) { + return mComputer.getProviderInfo(component, flags, userId); + } + + @Override + public ActivityInfo getReceiverInfo(ComponentName component, + @PackageManager.ComponentInfoFlagsBits long flags, int userId) { + return mComputer.getReceiverInfo(component, flags, userId); + } + + @Override + public @Nullable String getRotationResolverPackageName() { + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_defaultRotationResolverService)); + } + + @Override + public int getRuntimePermissionsVersion(@UserIdInt int userId) { + Preconditions.checkArgumentNonnegative(userId); + enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions( + "getRuntimePermissionVersion"); + return mSettings.getDefaultRuntimePermissionsVersion(userId); + } + + @Nullable + @Override + public ServiceInfo getServiceInfo(@NonNull ComponentName component, + @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) { + return mComputer.getServiceInfo(component, flags, userId); + } + + @Override + public @NonNull String getServicesSystemSharedLibraryPackageName() { + return mServicesExtensionPackageName; + } + + @Override + public String getSetupWizardPackageName() { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Non-system caller"); + } + return mPmInternal.getSetupWizardPackageName(); + } + + @Override + public ParceledListSlice getSharedLibraries(String packageName, + @PackageManager.PackageInfoFlagsBits long flags, int userId) { + return mComputer.getSharedLibraries(packageName, flags, userId); + } + + @Override + public @NonNull String getSharedSystemSharedLibraryPackageName() { + return mSharedSystemSharedLibraryPackageName; + } + + @Nullable + @Override + public KeySet getSigningKeySet(@NonNull String packageName) { + return mComputer.getSigningKeySet(packageName); + } + + @Override + public String getSplashScreenTheme(@NonNull String packageName, int userId) { + PackageStateInternal packageState = + getPackageStateInstalledFiltered(packageName, Binder.getCallingUid(), userId); + return packageState == null ? null + : packageState.getUserStateOrDefault(userId).getSplashScreenTheme(); + } + + @Override + public String getSdkSandboxPackageName() { + return mRequiredSdkSandboxPackage; + } + + @Override + public Bundle getSuspendedPackageAppExtras(String packageName, int userId) { + final int callingUid = Binder.getCallingUid(); + if (getPackageUid(packageName, 0, userId) != callingUid) { + throw new SecurityException("Calling package " + packageName + + " does not belong to calling uid " + callingUid); + } + return mSuspendPackageHelper.getSuspendedPackageAppExtras( + packageName, userId, callingUid); + } + + @Override + public @NonNull ParceledListSlice getSystemAvailableFeatures() { + // allow instant applications + ArrayList res; + synchronized (mAvailableFeatures) { + res = new ArrayList<>(mAvailableFeatures.size() + 1); + res.addAll(mAvailableFeatures.values()); + } + final FeatureInfo fi = new FeatureInfo(); + fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", + FeatureInfo.GL_ES_VERSION_UNDEFINED); + res.add(fi); + + return new ParceledListSlice<>(res); + } + + @Override + public String getSystemCaptionsServicePackageName() { + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_defaultSystemCaptionsService)); + } + + @Nullable + @Override + public String[] getSystemSharedLibraryNames() { + return mComputer.getSystemSharedLibraryNames(); + } + + @Override + public String getSystemTextClassifierPackageName() { + return ensureSystemPackageName( + mContext.getString(R.string.config_defaultTextClassifierPackage)); + } + + @Override + public int getTargetSdkVersion(@NonNull String packageName) { + return mComputer.getTargetSdkVersion(packageName); + } + + @Override + public int getUidForSharedUser(@NonNull String sharedUserName) { + return mComputer.getUidForSharedUser(sharedUserName); + } + + @Override + public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) { + Objects.requireNonNull(packageNames, "packageNames cannot be null"); + mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, + "getUnsuspendablePackagesForUser"); + final int callingUid = Binder.getCallingUid(); + if (UserHandle.getUserId(callingUid) != userId) { + throw new SecurityException("Calling uid " + callingUid + + " cannot query getUnsuspendablePackagesForUser for user " + userId); + } + return mSuspendPackageHelper.getUnsuspendablePackagesForUser(snapshotComputer(), + packageNames, userId, callingUid); + } + + @Override + public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.PACKAGE_VERIFICATION_AGENT, + "Only package verification agents can read the verifier device identity"); + + synchronized (mLock) { + return mSettings.getVerifierDeviceIdentityLPw(mLiveComputer); + } + } + + @Override + public String getWellbeingPackageName() { + final long identity = Binder.clearCallingIdentity(); + try { + return CollectionUtils.firstOrNull( + mContext.getSystemService(RoleManager.class).getRoleHolders( + RoleManager.ROLE_SYSTEM_WELLBEING)); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void grantImplicitAccess(int recipientUid, @NonNull String visibleAuthority) { + final Computer snapshot = snapshotComputer(); + final int recipientUserId = UserHandle.getUserId(recipientUid); + final ProviderInfo providerInfo = + snapshot.getGrantImplicitAccessProviderInfo(recipientUid, visibleAuthority); + if (providerInfo == null) { + return; + } + int visibleUid = providerInfo.applicationInfo.uid; + PackageManagerService.this.grantImplicitAccess(snapshot, recipientUserId, + null /*Intent*/, UserHandle.getAppId(recipientUid), visibleUid, + false /*direct*/, false /* retainOnUpdate */); + } + + // NOTE: Can't remove due to unsupported app usage + @Override + public void grantRuntimePermission(String packageName, String permName, final int userId) { + // Because this is accessed via the package manager service AIDL, + // go through the permission manager service AIDL + mContext.getSystemService(PermissionManager.class) + .grantRuntimePermission(packageName, permName, UserHandle.of(userId)); + } + + @Override + public boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate, + @PackageManager.CertificateInputType int type) { + return mComputer.hasSigningCertificate(packageName, certificate, type); + } + + @Override + public boolean hasSystemFeature(String name, int version) { + return PackageManagerService.this.hasSystemFeature(name, version); + } + + @Override + public boolean hasSystemUidErrors() { + // allow instant applications + return false; + } + + @Override + public boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate, + @PackageManager.CertificateInputType int type) { + return mComputer.hasUidSigningCertificate(uid, certificate, type); + } + + @Override + public void holdLock(IBinder token, int durationMs) { + mTestUtilityService.verifyHoldLockToken(token); + + synchronized (mLock) { + SystemClock.sleep(durationMs); + } + } + + /** + * @hide + */ + @Override + public int installExistingPackageAsUser(String packageName, int userId, int installFlags, + int installReason, List whiteListedPermissions) { + return mInstallPackageHelper.installExistingPackageAsUser(packageName, userId, installFlags, + installReason, whiteListedPermissions, null); + } + + @Override + public boolean isAutoRevokeWhitelisted(String packageName) { + int mode = mInjector.getSystemService(AppOpsManager.class).checkOpNoThrow( + AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, + Binder.getCallingUid(), packageName); + return mode == MODE_IGNORED; + } + + @Override + public boolean isDeviceUpgrading() { + return PackageManagerService.this.isDeviceUpgrading(); + } + + @Override + public boolean isFirstBoot() { + return PackageManagerService.this.isFirstBoot(); + } + + @Override + public boolean isInstantApp(String packageName, int userId) { + return mComputer.isInstantApp(packageName, userId); + } + + @Override + public boolean isOnlyCoreApps() { + return PackageManagerService.this.isOnlyCoreApps(); + } + + @Override + public boolean isPackageAvailable(String packageName, int userId) { + return mComputer.isPackageAvailable(packageName, userId); + } + + @Override + public boolean isPackageDeviceAdminOnAnyUser(String packageName) { + return PackageManagerService.this.isPackageDeviceAdminOnAnyUser(packageName); + } + + @Override + public boolean isPackageSignedByKeySet(@NonNull String packageName, @NonNull KeySet ks) { + return mComputer.isPackageSignedByKeySet(packageName, ks); + } + + @Override + public boolean isPackageSignedByKeySetExactly(@NonNull String packageName, @NonNull KeySet ks) { + return mComputer.isPackageSignedByKeySetExactly(packageName, ks); + } + + @Override + public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) { + final int callingUid = Binder.getCallingUid(); + final int callingAppId = UserHandle.getAppId(callingUid); + + enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/, + true /*checkShell*/, "isPackageStateProtected"); + + if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID + && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) { + throw new SecurityException("Caller must have the " + + MANAGE_DEVICE_ADMINS + " permission."); + } + + return mProtectedPackages.isPackageStateProtected(userId, packageName); + } + + @Override + public boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId) { + return mComputer.isPackageSuspendedForUser(packageName, userId); + } + + @Override + public boolean isProtectedBroadcast(String actionName) { + if (actionName != null) { + // TODO: remove these terrible hacks + if (actionName.startsWith("android.net.netmon.lingerExpired") + || actionName.startsWith("com.android.server.sip.SipWakeupTimer") + || actionName.startsWith("com.android.internal.telephony.data-reconnect") + || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { + return true; + } + } + // allow instant applications + synchronized (mProtectedBroadcasts) { + return mProtectedBroadcasts.contains(actionName); + } + } + + @Override + public boolean isSafeMode() { + // allow instant applications + return mSafeMode; + } + + @Override + public boolean isStorageLow() { + return PackageManagerService.this.isStorageLow(); + } + + @Override + public boolean isUidPrivileged(int uid) { + return mComputer.isUidPrivileged(uid); + } + + /** + * Logs process start information (including base APK hash) to the security log. + * @hide + */ + @Override + public void logAppProcessStartIfNeeded(String packageName, String processName, int uid, + String seinfo, String apkFile, int pid) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return; + } + if (!SecurityLog.isLoggingEnabled()) { + return; + } + mProcessLoggingHandler.logAppProcessStart(mContext, mPmInternal, apkFile, packageName, + processName, uid, seinfo, pid); + } + + @Override + public int movePackage(final String packageName, final String volumeUuid) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.MOVE_PACKAGE, null); + + final int callingUid = Binder.getCallingUid(); + final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid)); + final int moveId = mNextMoveId.getAndIncrement(); + mHandler.post(() -> { + try { + MovePackageHelper movePackageHelper = + new MovePackageHelper(PackageManagerService.this); + movePackageHelper.movePackageInternal( + packageName, volumeUuid, moveId, callingUid, user); + } catch (PackageManagerException e) { + Slog.w(PackageManagerService.TAG, "Failed to move " + packageName, e); + mMoveCallbacks.notifyStatusChanged(moveId, e.error); + } + }); + return moveId; + } + + @Override + public int movePrimaryStorage(String volumeUuid) throws RemoteException { + mContext.enforceCallingOrSelfPermission(Manifest.permission.MOVE_PACKAGE, null); + + final int realMoveId = mNextMoveId.getAndIncrement(); + final Bundle extras = new Bundle(); + extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); + mMoveCallbacks.notifyCreated(realMoveId, extras); + + final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { + @Override + public void onCreated(int moveId, Bundle extras) { + // Ignored + } + + @Override + public void onStatusChanged(int moveId, int status, long estMillis) { + mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); + } + }; + + final StorageManager storage = mInjector.getSystemService(StorageManager.class); + storage.setPrimaryStorageUuid(volumeUuid, callback); + return realMoveId; + } + + @Override + public void notifyDexLoad(String loadingPackageName, Map classLoaderContextMap, + String loaderIsa) { + int callingUid = Binder.getCallingUid(); + if (PackageManagerService.PLATFORM_PACKAGE_NAME.equals(loadingPackageName) && callingUid != Process.SYSTEM_UID) { + Slog.w(PackageManagerService.TAG, "Non System Server process reporting dex loads as system server. uid=" + + callingUid); + // Do not record dex loads from processes pretending to be system server. + // Only the system server should be assigned the package "android", so reject calls + // that don't satisfy the constraint. + // + // notifyDexLoad is a PM API callable from the app process. So in theory, apps could + // craft calls to this API and pretend to be system server. Doing so poses no particular + // danger for dex load reporting or later dexopt, however it is a sensible check to do + // in order to verify the expectations. + return; + } + + int userId = UserHandle.getCallingUserId(); + ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId); + if (ai == null) { + Slog.w(PackageManagerService.TAG, "Loading a package that does not exist for the calling user. package=" + + loadingPackageName + ", user=" + userId); + return; + } + mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId, + Process.isIsolated(callingUid)); + } + + @Override + public void notifyPackageUse(String packageName, int reason) { + final int callingUid = Binder.getCallingUid(); + final int callingUserId = UserHandle.getUserId(callingUid); + final boolean notify; + if (getInstantAppPackageName(callingUid) != null) { + notify = isCallerSameApp(packageName, callingUid); + } else { + notify = !isInstantAppInternal(packageName, callingUserId, Process.SYSTEM_UID); + } + if (!notify) { + return; + } + + notifyPackageUseInternal(packageName, reason); + } + + @Override + public void overrideLabelAndIcon(@NonNull ComponentName componentName, + @NonNull String nonLocalizedLabel, int icon, int userId) { + if (TextUtils.isEmpty(nonLocalizedLabel)) { + throw new IllegalArgumentException("Override label should be a valid String"); + } + updateComponentLabelIcon(componentName, nonLocalizedLabel, icon, userId); + } + + /** + * Ask the package manager to perform a dex-opt with the given compiler filter. + * + * Note: exposed only for the shell command to allow moving packages explicitly to a + * definite state. + */ + @Override + public boolean performDexOptMode(String packageName, + boolean checkProfiles, String targetCompilerFilter, boolean force, + boolean bootComplete, String splitName) { + return mDexOptHelper.performDexOptMode(packageName, checkProfiles, targetCompilerFilter, + force, bootComplete, splitName); + } + + /** + * Ask the package manager to perform a dex-opt with the given compiler filter on the + * secondary dex files belonging to the given package. + * + * Note: exposed only for the shell command to allow moving packages explicitly to a + * definite state. + */ + @Override + public boolean performDexOptSecondary(String packageName, String compilerFilter, + boolean force) { + return mDexOptHelper.performDexOptSecondary(packageName, compilerFilter, force); + } + + @NonNull + @Override + public ParceledListSlice queryContentProviders(@Nullable String processName, + int uid, @PackageManager.ComponentInfoFlagsBits long flags, + @Nullable String metaDataKey) { + return mComputer.queryContentProviders(processName, uid, flags, metaDataKey); + } + + @NonNull + @Override + public ParceledListSlice queryInstrumentation( + @NonNull String targetPackage, int flags) { + return mComputer.queryInstrumentation(targetPackage, flags); + } + + @Override + public @NonNull ParceledListSlice queryIntentActivities(Intent intent, + String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { + try { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); + + return new ParceledListSlice<>(snapshotComputer().queryIntentActivitiesInternal(intent, + resolvedType, flags, userId)); + } finally { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + } + + @Override + public @NonNull ParceledListSlice queryIntentActivityOptions(ComponentName caller, + Intent[] specifics, String[] specificTypes, Intent intent, + String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { + return new ParceledListSlice<>(mResolveIntentHelper.queryIntentActivityOptionsInternal( + snapshotComputer(), caller, specifics, specificTypes, intent, resolvedType, flags, + userId)); + } + + @Override + public @NonNull ParceledListSlice queryIntentContentProviders(Intent intent, + String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { + return new ParceledListSlice<>(mResolveIntentHelper.queryIntentContentProvidersInternal( + snapshotComputer(), intent, resolvedType, flags, userId)); + } + + @Override + public @NonNull ParceledListSlice queryIntentReceivers(Intent intent, + String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { + return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal( + snapshotComputer(), intent, resolvedType, flags, userId, Binder.getCallingUid())); + } + + @Override + public @NonNull ParceledListSlice queryIntentServices(Intent intent, + String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) { + final int callingUid = Binder.getCallingUid(); + return new ParceledListSlice<>(snapshotComputer().queryIntentServicesInternal( + intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/)); + } + + @Override + public ParceledListSlice queryProperty( + String propertyName, @PackageManager.PropertyLocation int componentType) { + Objects.requireNonNull(propertyName); + final int callingUid = Binder.getCallingUid(); + final int callingUserId = UserHandle.getCallingUserId(); + final List result = + mPackageProperty.queryProperty(propertyName, componentType, packageName -> { + final PackageStateInternal ps = getPackageStateInternal(packageName); + return shouldFilterApplication(ps, callingUid, callingUserId); + }); + if (result == null) { + return ParceledListSlice.emptyList(); + } + return new ParceledListSlice<>(result); + } + + @Deprecated + public void querySyncProviders(List outNames, List outInfo) { + mComputer.querySyncProviders(mSafeMode, outNames, outInfo); + } + + /** + * Reconcile the information we have about the secondary dex files belonging to + * {@code packageName} and the actual dex files. For all dex files that were + * deleted, update the internal records and delete the generated oat files. + */ + @Override + public void reconcileSecondaryDexFiles(String packageName) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return; + } else if (isInstantAppInternal( + packageName, UserHandle.getCallingUserId(), Process.SYSTEM_UID)) { + return; + } + mDexManager.reconcileSecondaryDexFiles(packageName); + } + + @Override + public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule, + IDexModuleRegisterCallback callback) { + int userId = UserHandle.getCallingUserId(); + ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId); + DexManager.RegisterDexModuleResult result; + if (ai == null) { + Slog.w(PackageManagerService.TAG, "Registering a dex module for a package that does not exist for the" + + " calling user. package=" + packageName + ", user=" + userId); + result = new DexManager.RegisterDexModuleResult(false, "Package not installed"); + } else { + result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId); + } + + if (callback != null) { + mHandler.post(() -> { + try { + callback.onDexModuleRegistered(dexModulePath, result.success, result.message); + } catch (RemoteException e) { + Slog.w(PackageManagerService.TAG, "Failed to callback after module registration " + dexModulePath, e); + } + }); + } + } + + @Override + public void registerMoveCallback(IPackageMoveObserver callback) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); + mMoveCallbacks.register(callback); + } + + // NOTE: Can't remove due to unsupported app usage + @Override + public void removePermission(String permName) { + // Because this is accessed via the package manager service AIDL, + // go through the permission manager service AIDL + mContext.getSystemService(PermissionManager.class).removePermission(permName); + } + + @Override + public void replacePreferredActivity(IntentFilter filter, int match, + ComponentName[] set, ComponentName activity, int userId) { + mPreferredActivityHelper.replacePreferredActivity(new WatchedIntentFilter(filter), + match, set, activity, userId); + } + + @Override + public void resetApplicationPreferences(int userId) { + mPreferredActivityHelper.resetApplicationPreferences(userId); + } + + @Override + public ProviderInfo resolveContentProvider(String name, + @PackageManager.ResolveInfoFlagsBits long flags, int userId) { + return mComputer.resolveContentProvider(name, flags, userId, Binder.getCallingUid()); + } + + @Override + public ResolveInfo resolveIntent(Intent intent, String resolvedType, + @PackageManager.ResolveInfoFlagsBits long flags, int userId) { + return mResolveIntentHelper.resolveIntentInternal(snapshotComputer(), intent, resolvedType, + flags, 0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid()); + } + + @Override + public ResolveInfo resolveService(Intent intent, String resolvedType, + @PackageManager.ResolveInfoFlagsBits long flags, int userId) { + final int callingUid = Binder.getCallingUid(); + return mResolveIntentHelper.resolveServiceInternal(snapshotComputer(), intent, resolvedType, + flags, userId, callingUid); + } + + @Override + public void restoreDefaultApps(byte[] backup, int userId) { + mPreferredActivityHelper.restoreDefaultApps(backup, userId); + } + + @Override + public void restoreDomainVerification(byte[] backup, int userId) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Only the system may call restorePreferredActivities()"); + } + + try { + ByteArrayInputStream input = new ByteArrayInputStream(backup); + TypedXmlPullParser parser = Xml.resolvePullParser(input); + + // User ID input isn't necessary here as it assumes the user integers match and that + // the only states inside the backup XML are for the target user. + mDomainVerificationManager.restoreSettings(snapshotComputer(), parser); + input.close(); + } catch (Exception e) { + if (PackageManagerService.DEBUG_BACKUP) { + Slog.e(PackageManagerService.TAG, "Exception restoring domain verification: " + e.getMessage()); + } + } + } + + @Override + public void restoreLabelAndIcon(@NonNull ComponentName componentName, int userId) { + updateComponentLabelIcon(componentName, null, null, userId); + } + + @Override + public void restorePreferredActivities(byte[] backup, int userId) { + mPreferredActivityHelper.restorePreferredActivities(backup, userId); + } + + @Override + public void sendDeviceCustomizationReadyBroadcast() { + mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY, + "sendDeviceCustomizationReadyBroadcast"); + + final long ident = Binder.clearCallingIdentity(); + try { + BroadcastHelper.sendDeviceCustomizationReadyBroadcast(); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override + public void setApplicationCategoryHint(String packageName, int categoryHint, + String callerPackageName) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + throw new SecurityException("Instant applications don't have access to this method"); + } + mInjector.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), + callerPackageName); + + final PackageStateMutator.InitialState initialState = recordInitialState(); + + final FunctionalUtils.ThrowingFunction + implementation = computer -> { + PackageStateInternal packageState = computer.getPackageStateFiltered(packageName, + Binder.getCallingUid(), UserHandle.getCallingUserId()); + if (packageState == null) { + throw new IllegalArgumentException("Unknown target package " + packageName); + } + + if (!Objects.equals(callerPackageName, + packageState.getInstallSource().installerPackageName)) { + throw new IllegalArgumentException("Calling package " + callerPackageName + + " is not installer for " + packageName); + } + + if (packageState.getCategoryOverride() != categoryHint) { + return commitPackageStateMutation(initialState, + packageName, state -> state.setCategoryOverride(categoryHint)); + } else { + return null; + } + }; + + PackageStateMutator.Result result = implementation.apply(snapshotComputer()); + if (result != null && result.isStateChanged() && !result.isSpecificPackageNull()) { + // TODO: Specific return value of what state changed? + // The installer on record might have changed, retry with lock + synchronized (mPackageStateWriteLock) { + result = implementation.apply(snapshotComputer()); + } + } + + if (result != null && result.isCommitted()) { + scheduleWriteSettings(); + } + } + + @Override + public void setApplicationEnabledSetting(String appPackageName, + int newState, int flags, int userId, String callingPackage) { + if (!mUserManager.exists(userId)) return; + if (callingPackage == null) { + callingPackage = Integer.toString(Binder.getCallingUid()); + } + + setEnabledSettings(List.of(new PackageManager.ComponentEnabledSetting(appPackageName, newState, flags)), + userId, callingPackage); + } + + @Override + public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, + int userId) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); + final int callingUid = Binder.getCallingUid(); + enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */, + true /* checkShell */, "setApplicationHiddenSetting for user " + userId); + + if (hidden && isPackageDeviceAdmin(packageName, userId)) { + Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); + return false; + } + + // Do not allow "android" is being disabled + if ("android".equals(packageName)) { + Slog.w(TAG, "Cannot hide package: android"); + return false; + } + + final long callingId = Binder.clearCallingIdentity(); + try { + final PackageStateInternal packageState = + mComputer.getPackageStateFiltered(packageName, callingUid, userId); + if (packageState == null) { + return false; + } + + // Cannot hide static shared libs as they are considered + // a part of the using app (emulating static linking). Also + // static libs are installed always on internal storage. + AndroidPackage pkg = packageState.getPkg(); + if (pkg != null) { + // Cannot hide SDK libs as they are controlled by SDK manager. + if (pkg.getSdkLibName() != null) { + Slog.w(TAG, "Cannot hide package: " + packageName + + " providing SDK library: " + + pkg.getSdkLibName()); + return false; + } + // Cannot hide static shared libs as they are considered + // a part of the using app (emulating static linking). Also + // static libs are installed always on internal storage. + if (pkg.getStaticSharedLibName() != null) { + Slog.w(TAG, "Cannot hide package: " + packageName + + " providing static shared library: " + + pkg.getStaticSharedLibName()); + return false; + } + } + // Only allow protected packages to hide themselves. + if (hidden && !UserHandle.isSameApp(callingUid, packageState.getAppId()) + && mProtectedPackages.isPackageStateProtected(userId, packageName)) { + Slog.w(TAG, "Not hiding protected package: " + packageName); + return false; + } + + if (packageState.getUserStateOrDefault(userId).isHidden() == hidden) { + return false; + } + + commitPackageStateMutation(null, packageName, packageState1 -> + packageState1.userState(userId).setHidden(hidden)); + + final PackageStateInternal newPackageState = getPackageStateInternal(packageName); + + if (hidden) { + killApplication(packageName, newPackageState.getAppId(), userId, "hiding pkg"); + sendApplicationHiddenForUser(packageName, newPackageState, userId); + } else { + sendPackageAddedForUser(packageName, newPackageState, userId, DataLoaderType.NONE); + } + + scheduleWritePackageRestrictions(userId); + return true; + } finally { + Binder.restoreCallingIdentity(callingId); + } + } + + @Override + public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, + int userId) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.DELETE_PACKAGES, null); + PackageStateInternal packageState = getPackageStateInternal(packageName); + if (packageState != null && packageState.getPkg() != null) { + AndroidPackage pkg = packageState.getPkg(); + // Cannot block uninstall SDK libs as they are controlled by SDK manager. + if (pkg.getSdkLibName() != null) { + Slog.w(PackageManagerService.TAG, "Cannot block uninstall of package: " + packageName + + " providing SDK library: " + pkg.getSdkLibName()); + return false; + } + // Cannot block uninstall of static shared libs as they are + // considered a part of the using app (emulating static linking). + // Also static libs are installed always on internal storage. + if (pkg.getStaticSharedLibName() != null) { + Slog.w(PackageManagerService.TAG, "Cannot block uninstall of package: " + packageName + + " providing static shared library: " + pkg.getStaticSharedLibName()); + return false; + } + } + synchronized (mLock) { + mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall); + } + + scheduleWritePackageRestrictions(userId); + return true; + } + + @Override + public void setComponentEnabledSetting(ComponentName componentName, + int newState, int flags, int userId) { + if (!mUserManager.exists(userId)) return; + + setEnabledSettings(List.of(new PackageManager.ComponentEnabledSetting(componentName, newState, flags)), + userId, null /* callingPackage */); + } + + @Override + public void setComponentEnabledSettings(List settings, int userId) { + if (!mUserManager.exists(userId)) return; + if (settings == null || settings.isEmpty()) { + throw new IllegalArgumentException("The list of enabled settings is empty"); + } + + setEnabledSettings(settings, userId, null /* callingPackage */); + } + + @Override + public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames, + int restrictionFlags, int userId) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, + "setDistractingPackageRestrictionsAsUser"); + + final int callingUid = Binder.getCallingUid(); + if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID + && UserHandle.getUserId(callingUid) != userId) { + throw new SecurityException("Calling uid " + callingUid + " cannot call for user " + + userId); + } + Objects.requireNonNull(packageNames, "packageNames cannot be null"); + if (restrictionFlags != 0 + && !mSuspendPackageHelper.isSuspendAllowedForUser(userId, callingUid)) { + Slog.w(PackageManagerService.TAG, "Cannot restrict packages due to restrictions on user " + userId); + return packageNames; + } + + final List changedPackagesList = new ArrayList<>(packageNames.length); + final IntArray changedUids = new IntArray(packageNames.length); + final List unactionedPackages = new ArrayList<>(packageNames.length); + + ArraySet changesToCommit = new ArraySet<>(); + Computer computer = snapshotComputer(); + final boolean[] canRestrict = (restrictionFlags != 0) + ? mSuspendPackageHelper.canSuspendPackageForUser(computer, packageNames, userId, + callingUid) : null; + for (int i = 0; i < packageNames.length; i++) { + final String packageName = packageNames[i]; + final PackageStateInternal packageState = + computer.getPackageStateInternal(packageName); + if (packageState == null + || computer.shouldFilterApplication(packageState, callingUid, userId)) { + Slog.w(PackageManagerService.TAG, "Could not find package setting for package: " + packageName + + ". Skipping..."); + unactionedPackages.add(packageName); + continue; + } + if (canRestrict != null && !canRestrict[i]) { + unactionedPackages.add(packageName); + continue; + } + final int oldDistractionFlags = packageState.getUserStateOrDefault(userId) + .getDistractionFlags(); + if (restrictionFlags != oldDistractionFlags) { + changedPackagesList.add(packageName); + changedUids.add(UserHandle.getUid(userId, packageState.getAppId())); + changesToCommit.add(packageName); + } + } + + commitPackageStateMutation(null, mutator -> { + final int size = changesToCommit.size(); + for (int index = 0; index < size; index++) { + mutator.forPackage(changesToCommit.valueAt(index)) + .userState(userId) + .setDistractionFlags(restrictionFlags); + } + }); + + if (!changedPackagesList.isEmpty()) { + final String[] changedPackages = changedPackagesList.toArray( + new String[changedPackagesList.size()]); + mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged( + changedPackages, changedUids.toArray(), userId, restrictionFlags)); + scheduleWritePackageRestrictions(userId); + } + return unactionedPackages.toArray(new String[0]); + } + + @Override + public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning, + int userId) { + final int callingUid = Binder.getCallingUid(); + final int callingAppId = UserHandle.getAppId(callingUid); + + enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/, + true /*checkShell*/, "setHarmfulAppInfo"); + + if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID && + checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) { + throw new SecurityException("Caller must have the " + + SET_HARMFUL_APP_WARNINGS + " permission."); + } + + PackageStateMutator.Result result = commitPackageStateMutation(null, packageName, + packageState -> packageState.userState(userId) + .setHarmfulAppWarning(warning == null ? null : warning.toString())); + if (result.isSpecificPackageNull()) { + throw new IllegalArgumentException("Unknown package: " + packageName); + } + scheduleWritePackageRestrictions(userId); + } + + @Override + public void setHomeActivity(ComponentName comp, int userId) { + mPreferredActivityHelper.setHomeActivity(comp, userId); + } + + @Override + public boolean setInstallLocation(int loc) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS, + null); + if (getInstallLocation() == loc) { + return true; + } + if (loc == InstallLocationUtils.APP_INSTALL_AUTO + || loc == InstallLocationUtils.APP_INSTALL_INTERNAL + || loc == InstallLocationUtils.APP_INSTALL_EXTERNAL) { + android.provider.Settings.Global.putInt(mContext.getContentResolver(), + android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); + return true; + } + return false; + } + + @Override + public void setInstallerPackageName(String targetPackage, String installerPackageName) { + final int callingUid = Binder.getCallingUid(); + final int callingUserId = UserHandle.getUserId(callingUid); + final FunctionalUtils.ThrowingCheckedFunction + implementation = computer -> { + if (computer.getInstantAppPackageName(callingUid) != null) { + return false; + } + + PackageStateInternal targetPackageState = + computer.getPackageStateInternal(targetPackage); + if (targetPackageState == null + || computer.shouldFilterApplication(targetPackageState, callingUid, + callingUserId)) { + throw new IllegalArgumentException("Unknown target package: " + targetPackage); + } + + PackageStateInternal installerPackageState = null; + if (installerPackageName != null) { + installerPackageState = computer.getPackageStateInternal(installerPackageName); + if (installerPackageState == null + || shouldFilterApplication( + installerPackageState, callingUid, callingUserId)) { + throw new IllegalArgumentException("Unknown installer package: " + + installerPackageName); + } + } + + Signature[] callerSignature; + final int appId = UserHandle.getAppId(callingUid); + Pair either = + computer.getPackageOrSharedUser(appId); + if (either != null) { + if (either.first != null) { + callerSignature = either.first.getSigningDetails().getSignatures(); + } else { + callerSignature = either.second.getSigningDetails().getSignatures(); + } + } else { + throw new SecurityException("Unknown calling UID: " + callingUid); + } + + // Verify: can't set installerPackageName to a package that is + // not signed with the same cert as the caller. + if (installerPackageState != null) { + if (compareSignatures(callerSignature, + installerPackageState.getSigningDetails().getSignatures()) + != PackageManager.SIGNATURE_MATCH) { + throw new SecurityException( + "Caller does not have same cert as new installer package " + + installerPackageName); + } + } + + // Verify: if target already has an installer package, it must + // be signed with the same cert as the caller. + String targetInstallerPackageName = + targetPackageState.getInstallSource().installerPackageName; + PackageStateInternal targetInstallerPkgSetting = targetInstallerPackageName == null + ? null : computer.getPackageStateInternal(targetInstallerPackageName); + + if (targetInstallerPkgSetting != null) { + if (compareSignatures(callerSignature, + targetInstallerPkgSetting.getSigningDetails().getSignatures()) + != PackageManager.SIGNATURE_MATCH) { + throw new SecurityException( + "Caller does not have same cert as old installer package " + + targetInstallerPackageName); + } + } else if (mContext.checkCallingOrSelfPermission( + Manifest.permission.INSTALL_PACKAGES) != PERMISSION_GRANTED) { + // This is probably an attempt to exploit vulnerability b/150857253 of taking + // privileged installer permissions when the installer has been uninstalled or + // was never set. + EventLog.writeEvent(0x534e4554, "150857253", callingUid, ""); + + final long binderToken = Binder.clearCallingIdentity(); + try { + if (mInjector.getCompatibility().isChangeEnabledByUid( + PackageManagerService.THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE, + callingUid)) { + throw new SecurityException("Neither user " + callingUid + + " nor current process has " + + Manifest.permission.INSTALL_PACKAGES); + } else { + // If change disabled, fail silently for backwards compatibility + return false; + } + } finally { + Binder.restoreCallingIdentity(binderToken); + } + } + + return true; + }; + PackageStateMutator.InitialState initialState = recordInitialState(); + boolean allowed = implementation.apply(snapshotComputer()); + if (allowed) { + // TODO: Need to lock around here to handle mSettings.addInstallerPackageNames, + // should find an alternative which avoids any race conditions + PackageStateInternal targetPackageState; + synchronized (mLock) { + PackageStateMutator.Result result = commitPackageStateMutation(initialState, + targetPackage, state -> state.setInstaller(installerPackageName)); + if (result.isPackagesChanged() || result.isStateChanged()) { + synchronized (mPackageStateWriteLock) { + allowed = implementation.apply(snapshotComputer()); + if (allowed) { + commitPackageStateMutation(null, targetPackage, + state -> state.setInstaller(installerPackageName)); + } else { + return; + } + } + } + targetPackageState = getPackageStateInternal(targetPackage); + mSettings.addInstallerPackageNames(targetPackageState.getInstallSource()); + } + mAppsFilter.addPackage(targetPackageState); + scheduleWriteSettings(); + } + } + + @Override + public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) { + if (HIDE_EPHEMERAL_APIS) { + return true; + } + + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, true /* checkShell */, + "setInstantAppCookie"); + if (!isCallerSameApp(packageName, Binder.getCallingUid())) { + return false; + } + + PackageStateInternal packageState = getPackageStateInternal(packageName); + if (packageState == null || packageState.getPkg() == null) { + return false; + } + return mInstantAppRegistry.setInstantAppCookie(packageState.getPkg(), cookie, + mContext.getPackageManager().getInstantAppCookieMaxBytes(), userId); + } + + @Override + public void setKeepUninstalledPackages(List packageList) { + mContext.enforceCallingPermission( + Manifest.permission.KEEP_UNINSTALLED_PACKAGES, + "setKeepUninstalledPackages requires KEEP_UNINSTALLED_PACKAGES permission"); + Objects.requireNonNull(packageList); + + setKeepUninstalledPackagesInternal(packageList); + } + + @Override + public void setLastChosenActivity(Intent intent, String resolvedType, int flags, + IntentFilter filter, int match, ComponentName activity) { + mPreferredActivityHelper.setLastChosenActivity(intent, resolvedType, flags, + new WatchedIntentFilter(filter), match, activity); + } + + @Override + public void setMimeGroup(String packageName, String mimeGroup, List mimeTypes) { + enforceOwnerRights(packageName, Binder.getCallingUid()); + mimeTypes = CollectionUtils.emptyIfNull(mimeTypes); + final PackageStateInternal packageState = getPackageStateInternal(packageName); + Set existingMimeTypes = packageState.getMimeGroups().get(mimeGroup); + if (existingMimeTypes == null) { + throw new IllegalArgumentException("Unknown MIME group " + mimeGroup + + " for package " + packageName); + } + if (existingMimeTypes.size() == mimeTypes.size() + && existingMimeTypes.containsAll(mimeTypes)) { + return; + } + + ArraySet mimeTypesSet = new ArraySet<>(mimeTypes); + commitPackageStateMutation(null, packageName, packageStateWrite -> { + packageStateWrite.setMimeGroup(mimeGroup, mimeTypesSet); + }); + if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) { + Binder.withCleanCallingIdentity(() -> + mPreferredActivityHelper.clearPackagePreferredActivities(packageName, + UserHandle.USER_ALL)); + } + + scheduleWriteSettings(); + } + + @Override + public void setPackageStoppedState(String packageName, boolean stopped, int userId) { + PackageManagerService.this + .setPackageStoppedState(snapshotComputer(), packageName, stopped, userId); + } + + @Override + public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, + PersistableBundle appExtras, PersistableBundle launcherExtras, + SuspendDialogInfo dialogInfo, String callingPackage, int userId) { + final int callingUid = Binder.getCallingUid(); + enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId, + "setPackagesSuspendedAsUser"); + return mSuspendPackageHelper.setPackagesSuspended(snapshotComputer(), packageNames, + suspended, appExtras, launcherExtras, dialogInfo, callingPackage, userId, + callingUid); + } + + @Override + public boolean setRequiredForSystemUser(String packageName, boolean requiredForSystemUser) { + PackageManagerServiceUtils.enforceSystemOrRoot( + "setRequiredForSystemUser can only be run by the system or root"); + + PackageStateMutator.Result result = commitPackageStateMutation(null, packageName, + packageState -> packageState.setRequiredForSystemUser(requiredForSystemUser)); + if (!result.isCommitted()) { + return false; + } + + scheduleWriteSettings(); + return true; + } + + @Override + public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) { + Preconditions.checkArgumentNonnegative(version); + Preconditions.checkArgumentNonnegative(userId); + enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions( + "setRuntimePermissionVersion"); + mSettings.setDefaultRuntimePermissionsVersion(version, userId); + } + + @Override + public void setSplashScreenTheme(@NonNull String packageName, @Nullable String themeId, + int userId) { + final int callingUid = Binder.getCallingUid(); + enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */, + false /* checkShell */, "setSplashScreenTheme"); + enforceOwnerRights(packageName, callingUid); + + PackageStateInternal packageState = getPackageStateInstalledFiltered(packageName, + callingUid, userId); + if (packageState == null) { + return; + } + + commitPackageStateMutation(null, packageName, state -> + state.userState(userId).setSplashScreenTheme(themeId)); + } + + @Override + public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) { + final int callingUid = Binder.getCallingUid(); + final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID + || callingUid == Process.SYSTEM_UID; + if (!calledFromSystemOrPhone) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, + "setSystemAppHiddenUntilInstalled"); + } + + final PackageStateInternal stateRead = getPackageStateInternal(packageName); + if (stateRead == null || !stateRead.isSystem() || stateRead.getPkg() == null) { + return; + } + if (stateRead.getPkg().isCoreApp() && !calledFromSystemOrPhone) { + throw new SecurityException("Only system or phone callers can modify core apps"); + } + + commitPackageStateMutation(null, mutator -> { + mutator.forPackage(packageName) + .setHiddenUntilInstalled(hidden); + mutator.forDisabledSystemPackage(packageName) + .setHiddenUntilInstalled(hidden); + }); + } + + @Override + public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) { + final int callingUid = Binder.getCallingUid(); + final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID + || callingUid == Process.SYSTEM_UID; + if (!calledFromSystemOrPhone) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, + "setSystemAppHiddenUntilInstalled"); + } + + final PackageStateInternal packageState = getPackageStateInternal(packageName); + // The target app should always be in system + if (packageState == null || !packageState.isSystem() || packageState.getPkg() == null) { + return false; + } + if (packageState.getPkg().isCoreApp() && !calledFromSystemOrPhone) { + throw new SecurityException("Only system or phone callers can modify core apps"); + } + // Check if the install state is the same + if (packageState.getUserStateOrDefault(userId).isInstalled() == installed) { + return false; + } + + final long callingId = Binder.clearCallingIdentity(); + try { + if (installed) { + // install the app from uninstalled state + installExistingPackageAsUser( + packageName, + userId, + PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS, + PackageManager.INSTALL_REASON_DEVICE_SETUP, + null); + return true; + } + + // uninstall the app from installed state + deletePackageVersioned( + new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST), + new PackageManager.LegacyPackageDeleteObserver(null).getBinder(), + userId, + PackageManager.DELETE_SYSTEM_APP); + return true; + } finally { + Binder.restoreCallingIdentity(callingId); + } + } + + @Override + public void setUpdateAvailable(String packageName, boolean updateAvailable) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null); + commitPackageStateMutation(null, packageName, state -> + state.setUpdateAvailable(updateAvailable)); + } + + @Override + public void unregisterMoveCallback(IPackageMoveObserver callback) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); + mMoveCallbacks.unregister(callback); + } + + @Deprecated + @Override + public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { + return mDomainVerificationManager.setLegacyUserState(packageName, userId, status); + } + + @Deprecated + @Override + public void verifyIntentFilter(int id, int verificationCode, List failedDomains) { + DomainVerificationProxyV1.queueLegacyVerifyResult(mContext, mDomainVerificationConnection, + id, verificationCode, failedDomains, Binder.getCallingUid()); + } + + @Override + public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.PACKAGE_VERIFICATION_AGENT, + "Only package verification agents can verify applications"); + final int callingUid = Binder.getCallingUid(); + + final Message msg = mHandler.obtainMessage(PackageManagerService.PACKAGE_VERIFIED); + final PackageVerificationResponse response = new PackageVerificationResponse( + verificationCode, callingUid); + msg.arg1 = id; + msg.obj = response; + mHandler.sendMessage(msg); + } + + @Override + public void requestPackageChecksums(@NonNull String packageName, boolean includeSplits, + @Checksum.TypeMask int optional, @Checksum.TypeMask int required, + @Nullable List trustedInstallers, + @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId) { + requestChecksumsInternal(packageName, includeSplits, optional, required, trustedInstallers, + onChecksumsReadyListener, userId, mInjector.getBackgroundExecutor(), + mInjector.getBackgroundHandler()); + } + + @Override + public void notifyPackagesReplacedReceived(String[] packages) { + Computer computer = snapshotComputer(); + ArraySet packagesToNotify = computer.getNotifyPackagesForReplacedReceived(packages); + for (int index = 0; index < packagesToNotify.size(); index++) { + notifyInstallObserver(packagesToNotify.valueAt(index), false /* killApp */); + } + } + + @Override + public boolean canPackageQuery(@NonNull String sourcePackageName, + @NonNull String targetPackageName, @UserIdInt int userId) { + return mComputer.canPackageQuery(sourcePackageName, targetPackageName, userId); + } + + @Override + public boolean onTransact(int code, Parcel data, Parcel reply, int flags) + throws RemoteException { + try { + return super.onTransact(code, data, reply, flags); + } catch (RuntimeException e) { + if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException) + && !(e instanceof ParcelableException)) { + Slog.wtf(TAG, "Package Manager Unexpected Exception", e); + } + throw e; + } + } + + @Override + public void onShellCommand(FileDescriptor in, FileDescriptor out, + FileDescriptor err, String[] args, ShellCallback callback, + ResultReceiver resultReceiver) { + (new PackageManagerShellCommand(mIPackageManager, + mContext,mDomainVerificationManager.getShell())) + .exec(this, in, out, err, args, callback, resultReceiver); + } + + @SuppressWarnings("resource") + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; + new DumpHelper(PackageManagerService.this).doDump(fd, pw, args); + } + } + private class PackageManagerLocalImpl implements PackageManagerLocal { } @@ -6865,7 +7173,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean isInstantApp(String packageName, int userId) { - return PackageManagerService.this.isInstantApp(packageName, userId); + return PackageManagerService.this.mIPackageManager.isInstantApp(packageName, userId); } @Override @@ -7226,7 +7534,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String getNameForUid(int uid) { - return PackageManagerService.this.getNameForUid(uid); + return mIPackageManager.getNameForUid(uid); } @Override @@ -7471,7 +7779,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean isOnlyCoreApps() { - return PackageManagerService.this.isOnlyCoreApps(); + return mIPackageManager.isOnlyCoreApps(); } @Override @@ -7480,6 +7788,11 @@ public class PackageManagerService extends IPackageManager.Stub PackageManagerService.this.freeStorage(volumeUuid, bytes, flags); } + @Override + public void freeAllAppCacheAboveQuota(@NonNull String volumeUuid) throws IOException { + PackageManagerService.this.freeAllAppCacheAboveQuota(volumeUuid); + } + @Override public void forEachPackageSetting(Consumer actionLocked) { PackageManagerService.this.forEachPackageSetting(actionLocked); @@ -7558,7 +7871,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void finishPackageInstall(int token, boolean didLaunch) { - PackageManagerService.this.finishPackageInstall(token, didLaunch); + mIPackageManager.finishPackageInstall(token, didLaunch); } @Nullable @@ -7803,6 +8116,16 @@ public class PackageManagerService extends IPackageManager.Stub public Computer snapshot() { return snapshotComputer(); } + + @Override + public void shutdown() { + PackageManagerService.this.shutdown(); + } + + @Override + public DynamicCodeLogger getDynamicCodeLogger() { + return PackageManagerService.this.getDexManager().getDynamicCodeLogger(); + } } private boolean setEnabledOverlayPackages(@UserIdInt int userId, @@ -7886,23 +8209,6 @@ public class PackageManagerService extends IPackageManager.Stub return true; } - @Override - public int getRuntimePermissionsVersion(@UserIdInt int userId) { - Preconditions.checkArgumentNonnegative(userId); - enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions( - "getRuntimePermissionVersion"); - return mSettings.getDefaultRuntimePermissionsVersion(userId); - } - - @Override - public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) { - Preconditions.checkArgumentNonnegative(version); - Preconditions.checkArgumentNonnegative(userId); - enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions( - "setRuntimePermissionVersion"); - mSettings.setDefaultRuntimePermissionsVersion(version, userId); - } - private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions( @NonNull String message) { if (mContext.checkCallingOrSelfPermission( @@ -8031,23 +8337,6 @@ public class PackageManagerService extends IPackageManager.Stub return mPackageUsage.isHistoricalPackageUsageAvailable(); } - /** - * Logs process start information (including base APK hash) to the security log. - * @hide - */ - @Override - public void logAppProcessStartIfNeeded(String packageName, String processName, int uid, - String seinfo, String apkFile, int pid) { - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { - return; - } - if (!SecurityLog.isLoggingEnabled()) { - return; - } - mProcessLoggingHandler.logAppProcessStart(mContext, mPmInternal, apkFile, packageName, - processName, uid, seinfo, pid); - } - public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) { return getOrCreateCompilerPackageStats(pkg.getPackageName()); } @@ -8056,26 +8345,6 @@ public class PackageManagerService extends IPackageManager.Stub return mCompilerStats.getOrCreatePackageStats(pkgName); } - @Override - public boolean isAutoRevokeWhitelisted(String packageName) { - int mode = mInjector.getSystemService(AppOpsManager.class).checkOpNoThrow( - AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, - Binder.getCallingUid(), packageName); - return mode == MODE_IGNORED; - } - - @PackageManager.InstallReason - @Override - public int getInstallReason(@NonNull String packageName, @UserIdInt int userId) { - return mComputer.getInstallReason(packageName, userId); - } - - @Override - public boolean canRequestPackageInstalls(String packageName, int userId) { - return mComputer.canRequestPackageInstalls(packageName, Binder.getCallingUid(), userId, - true /* throwIfPermNotDeclared*/); - } - /** * Returns true if the system or user is explicitly preventing an otherwise valid installer to * complete an install. This includes checks like unknown sources and user restrictions. @@ -8084,45 +8353,35 @@ public class PackageManagerService extends IPackageManager.Stub return mComputer.isInstallDisabledForPackage(packageName, uid, userId); } - @Override - public ComponentName getInstantAppResolverSettingsComponent() { - return mInstantAppResolverSettingsComponent; - } - - @Override - public ComponentName getInstantAppInstallerComponent() { - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { - return null; - } - return mInstantAppInstallerActivity == null - ? null : mInstantAppInstallerActivity.getComponentName(); - } - - @Override - public String getInstantAppAndroidId(String packageName, int userId) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS, - "getInstantAppAndroidId"); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, - false /* checkShell */, "getInstantAppAndroidId"); - // Make sure the target is an Instant App. - if (!isInstantApp(packageName, userId)) { - return null; - } - return mInstantAppRegistry.getInstantAppAndroidId(packageName, userId); - } - - @Override - public void grantImplicitAccess(int recipientUid, @NonNull String visibleAuthority) { - final int callingUid = Binder.getCallingUid(); - final int recipientUserId = UserHandle.getUserId(recipientUid); - final ProviderInfo providerInfo = - mComputer.getGrantImplicitAccessProviderInfo(recipientUid, visibleAuthority); - if (providerInfo == null) { + private void grantImplicitAccess(@NonNull Computer snapshot, @UserIdInt int userId, + Intent intent, @AppIdInt int recipientAppId, int visibleUid, boolean direct, + boolean retainOnUpdate) { + final AndroidPackage visiblePackage = snapshot.getPackage(visibleUid); + final int recipientUid = UserHandle.getUid(userId, recipientAppId); + if (visiblePackage == null || snapshot.getPackage(recipientUid) == null) { return; } - int visibleUid = providerInfo.applicationInfo.uid; - mPmInternal.grantImplicitAccess(recipientUserId, null /*Intent*/, - UserHandle.getAppId(recipientUid), visibleUid, false /*direct*/); + + final boolean instantApp = snapshot.isInstantAppInternal( + visiblePackage.getPackageName(), userId, visibleUid); + final boolean accessGranted; + if (instantApp) { + if (!direct) { + // if the interaction that lead to this granting access to an instant app + // was indirect (i.e.: URI permission grant), do not actually execute the + // grant. + return; + } + accessGranted = mInstantAppRegistry.grantInstantAccess(userId, intent, + recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/); + } else { + accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid, + retainOnUpdate); + } + + if (accessGranted) { + ApplicationPackageManager.invalidateGetPackagesForUidCache(); + } } boolean canHaveOatDir(String packageName) { @@ -8148,100 +8407,6 @@ public class PackageManagerService extends IPackageManager.Stub return mComputer.getUnusedPackages(downgradeTimeThresholdMillis); } - @Override - public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning, - int userId) { - final int callingUid = Binder.getCallingUid(); - final int callingAppId = UserHandle.getAppId(callingUid); - - enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/, - true /*checkShell*/, "setHarmfulAppInfo"); - - if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID && - checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) { - throw new SecurityException("Caller must have the " - + SET_HARMFUL_APP_WARNINGS + " permission."); - } - - PackageStateMutator.Result result = commitPackageStateMutation(null, packageName, - packageState -> packageState.userState(userId) - .setHarmfulAppWarning(warning == null ? null : warning.toString())); - if (result.isSpecificPackageNull()) { - throw new IllegalArgumentException("Unknown package: " + packageName); - } - scheduleWritePackageRestrictions(userId); - } - - @Nullable - @Override - public CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId) { - return mComputer.getHarmfulAppWarning(packageName, userId); - } - - @Override - public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) { - final int callingUid = Binder.getCallingUid(); - final int callingAppId = UserHandle.getAppId(callingUid); - - enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/, - true /*checkShell*/, "isPackageStateProtected"); - - if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID - && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) { - throw new SecurityException("Caller must have the " - + MANAGE_DEVICE_ADMINS + " permission."); - } - - return mProtectedPackages.isPackageStateProtected(userId, packageName); - } - - @Override - public void sendDeviceCustomizationReadyBroadcast() { - mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY, - "sendDeviceCustomizationReadyBroadcast"); - - final long ident = Binder.clearCallingIdentity(); - try { - BroadcastHelper.sendDeviceCustomizationReadyBroadcast(); - } finally { - Binder.restoreCallingIdentity(ident); - } - } - - @Override - public void setMimeGroup(String packageName, String mimeGroup, List mimeTypes) { - enforceOwnerRights(packageName, Binder.getCallingUid()); - mimeTypes = CollectionUtils.emptyIfNull(mimeTypes); - final PackageStateInternal packageState = getPackageStateInternal(packageName); - Set existingMimeTypes = packageState.getMimeGroups().get(mimeGroup); - if (existingMimeTypes == null) { - throw new IllegalArgumentException("Unknown MIME group " + mimeGroup - + " for package " + packageName); - } - if (existingMimeTypes.size() == mimeTypes.size() - && existingMimeTypes.containsAll(mimeTypes)) { - return; - } - - ArraySet mimeTypesSet = new ArraySet<>(mimeTypes); - commitPackageStateMutation(null, packageName, packageStateWrite -> { - packageStateWrite.setMimeGroup(mimeGroup, mimeTypesSet); - }); - if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) { - Binder.withCleanCallingIdentity(() -> - mPreferredActivityHelper.clearPackagePreferredActivities(packageName, - UserHandle.USER_ALL)); - } - - scheduleWriteSettings(); - } - - @Override - public List getMimeGroup(String packageName, String mimeGroup) { - enforceOwnerRights(packageName, Binder.getCallingUid()); - return getMimeGroupInternal(packageName, mimeGroup); - } - private List getMimeGroupInternal(String packageName, String mimeGroup) { final PackageStateInternal packageState = getPackageStateInternal(packageName); if (packageState == null) { @@ -8257,32 +8422,6 @@ public class PackageManagerService extends IPackageManager.Stub return new ArrayList<>(mimeTypes); } - @Override - public void setSplashScreenTheme(@NonNull String packageName, @Nullable String themeId, - int userId) { - final int callingUid = Binder.getCallingUid(); - enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */, - false /* checkShell */, "setSplashScreenTheme"); - enforceOwnerRights(packageName, callingUid); - - PackageStateInternal packageState = getPackageStateInstalledFiltered(packageName, - callingUid, userId); - if (packageState == null) { - return; - } - - commitPackageStateMutation(null, packageName, state -> - state.userState(userId).setSplashScreenTheme(themeId)); - } - - @Override - public String getSplashScreenTheme(@NonNull String packageName, int userId) { - PackageStateInternal packageState = - getPackageStateInstalledFiltered(packageName, Binder.getCallingUid(), userId); - return packageState == null ? null - : packageState.getUserStateOrDefault(userId).getSplashScreenTheme(); - } - /** * Temporary method that wraps mSettings.writeLPr() and calls mPermissionManager's * writeLegacyPermissionsTEMP() beforehand. @@ -8295,21 +8434,6 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writeLPr(mLiveComputer); } - @Override - public IBinder getHoldLockToken() { - if (!Build.IS_DEBUGGABLE) { - throw new SecurityException("getHoldLockToken requires a debuggable build"); - } - - mContext.enforceCallingPermission( - Manifest.permission.INJECT_EVENTS, - "getHoldLockToken requires INJECT_EVENTS permission"); - - final Binder token = new Binder(); - token.attachInterface(this, "holdLock:" + Binder.getCallingUid()); - return token; - } - @Override public void verifyHoldLockToken(IBinder token) { if (!Build.IS_DEBUGGABLE) { @@ -8325,15 +8449,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public void holdLock(IBinder token, int durationMs) { - mTestUtilityService.verifyHoldLockToken(token); - - synchronized (mLock) { - SystemClock.sleep(durationMs); - } - } - static String getDefaultTimeouts() { final long token = Binder.clearCallingIdentity(); try { @@ -8431,16 +8546,6 @@ public class PackageManagerService extends IPackageManager.Stub return result.toArray(new PerUidReadTimeouts[result.size()]); } - @Override - public void setKeepUninstalledPackages(List packageList) { - mContext.enforceCallingPermission( - Manifest.permission.KEEP_UNINSTALLED_PACKAGES, - "setKeepUninstalledPackages requires KEEP_UNINSTALLED_PACKAGES permission"); - Objects.requireNonNull(packageList); - - setKeepUninstalledPackagesInternal(packageList); - } - private void setKeepUninstalledPackagesInternal(List packageList) { Preconditions.checkNotNull(packageList); synchronized (mKeepUninstalledPackages) { @@ -8462,19 +8567,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - @Override - public IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage, - String featureId, int userId) throws RemoteException { - return mResolveIntentHelper.getLaunchIntentSenderForPackage(snapshotComputer(), - packageName, callingPackage, featureId, userId); - } - - @Override - public boolean canPackageQuery(@NonNull String sourcePackageName, - @NonNull String targetPackageName, @UserIdInt int userId) { - return mComputer.canPackageQuery(sourcePackageName, targetPackageName, userId); - } - boolean getSafeMode() { return mSafeMode; } diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 500b4ec70c44e..b92f51b392f92 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -159,9 +159,9 @@ class PackageManagerShellCommand extends ShellCommand { private static final SecureRandom RANDOM = new SecureRandom(); - PackageManagerShellCommand(@NonNull PackageManagerService service, + PackageManagerShellCommand(@NonNull IPackageManager packageManager, @NonNull Context context, @NonNull DomainVerificationShell domainVerificationShell) { - mInterface = service; + mInterface = packageManager; mLegacyPermissionManager = LocalServices.getService(LegacyPermissionManagerInternal.class); mPermissionManager = context.getSystemService(PermissionManager.class); mContext = context; diff --git a/services/core/java/com/android/server/pm/PreferredActivityHelper.java b/services/core/java/com/android/server/pm/PreferredActivityHelper.java index 8c49bafa06a85..7253ae4e7cb06 100644 --- a/services/core/java/com/android/server/pm/PreferredActivityHelper.java +++ b/services/core/java/com/android/server/pm/PreferredActivityHelper.java @@ -151,7 +151,8 @@ final class PreferredActivityHelper { if (TextUtils.equals(currentPackageName, packageName)) { return false; } - final String[] callingPackages = mPm.getPackagesForUid(Binder.getCallingUid()); + final String[] callingPackages = mPm.mIPackageManager + .getPackagesForUid(Binder.getCallingUid()); if (callingPackages != null && ArrayUtils.contains(callingPackages, mPm.mRequiredPermissionControllerPackage)) { // PermissionController manages default home directly. diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index d99305d728b98..006e82bdbcb47 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -6297,7 +6297,8 @@ public class UserManagerService extends IUserManager.Stub { * {@link SecurityException} if not. */ private void verifyCallingPackage(String callingPackage, int callingUid) { - int packageUid = mPm.getPackageUid(callingPackage, 0, UserHandle.getUserId(callingUid)); + int packageUid = mPm.snapshotComputer() + .getPackageUid(callingPackage, 0, UserHandle.getUserId(callingUid)); if (packageUid != callingUid) { throw new SecurityException("Specified package " + callingPackage + " does not match the calling uid " + callingUid); diff --git a/services/core/java/com/android/server/pm/VerificationParams.java b/services/core/java/com/android/server/pm/VerificationParams.java index 4334cbdce1f2d..bc936112649f9 100644 --- a/services/core/java/com/android/server/pm/VerificationParams.java +++ b/services/core/java/com/android/server/pm/VerificationParams.java @@ -372,9 +372,10 @@ final class VerificationParams extends HandlerParams { * Determine if we have any installed package verifiers. If we * do, then we'll defer to them to verify the packages. */ + final Computer snapshot = mPm.snapshotComputer(); final int requiredUid = requiredVerifierPackage == null ? -1 - : mPm.getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, - verifierUserId); + : snapshot.getPackageUid(requiredVerifierPackage, + MATCH_DEBUG_TRIAGED_MISSING, verifierUserId); verificationState.setRequiredVerifierUid(requiredUid); final boolean isVerificationEnabled = isVerificationEnabled(pkgLite, verifierUserId); @@ -391,8 +392,8 @@ final class VerificationParams extends HandlerParams { verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Query all live verifiers based on current user state - final ParceledListSlice receivers = mPm.queryIntentReceivers(verification, - PACKAGE_MIME_TYPE, 0, verifierUserId); + final ParceledListSlice receivers = mPm.queryIntentReceivers(snapshot, + verification, PACKAGE_MIME_TYPE, 0, verifierUserId); if (DEBUG_VERIFY) { Slog.d(TAG, "Found " + receivers.getList().size() + " verifiers for intent " diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index dcfb8b5e7b332..a82d4eaa5b28b 100644 --- a/services/core/java/com/android/server/power/ShutdownThread.java +++ b/services/core/java/com/android/server/power/ShutdownThread.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManagerInternal; import android.media.AudioAttributes; import android.os.FileUtils; import android.os.Handler; @@ -525,8 +526,7 @@ public final class ShutdownThread extends Thread { shutdownTimingLog.traceBegin("ShutdownPackageManager"); metricStarted(METRIC_PM); - final PackageManagerService pm = (PackageManagerService) - ServiceManager.getService("package"); + final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class); if (pm != null) { pm.shutdown(); } diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java index c0207f044b831..16592d764e644 100644 --- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java +++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java @@ -24,6 +24,7 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.pm.PackageManagerInternal; import android.os.Binder; import android.os.Environment; import android.os.FileObserver; @@ -31,7 +32,6 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.os.ResultReceiver; -import android.os.ServiceManager; import android.os.ShellCallback; import android.os.ShellCommand; import android.os.UserHandle; @@ -49,6 +49,7 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.EventLogTags; +import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.pm.PackageManagerService; @@ -187,10 +188,10 @@ public class DeviceStorageMonitorService extends SystemService { // when it's within 150% of the threshold, we try trimming usage // back to 200% of the threshold. if (file.getUsableSpace() < (lowBytes * 3) / 2) { - final PackageManagerService pms = (PackageManagerService) ServiceManager - .getService("package"); + final PackageManagerInternal pm = + LocalServices.getService(PackageManagerInternal.class); try { - pms.freeStorage(vol.getFsUuid(), lowBytes * 2, 0); + pm.freeStorage(vol.getFsUuid(), lowBytes * 2, 0); } catch (IOException e) { Slog.w(TAG, e); } @@ -264,10 +265,10 @@ public class DeviceStorageMonitorService extends SystemService { for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { final File file = vol.getPath(); if (file.getUsableSpace() < file.getTotalSpace() * storageThresholdPercentHigh / 100) { - final PackageManagerService pms = (PackageManagerService) ServiceManager - .getService("package"); + final PackageManagerInternal pm = + LocalServices.getService(PackageManagerInternal.class); try { - pms.freeAllAppCacheAboveQuota(vol.getFsUuid()); + pm.freeAllAppCacheAboveQuota(vol.getFsUuid()); } catch (IOException e) { Slog.w(TAG, e); } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 294dc8941983a..fa2850a5157da 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -41,6 +41,7 @@ import android.app.usage.UsageStatsManagerInternal; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.pm.IPackageManager; import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; @@ -1225,12 +1226,15 @@ public final class SystemServer implements Dumpable { mSystemServiceManager.startService(domainVerificationService); t.traceEnd(); + IPackageManager iPackageManager; t.traceBegin("StartPackageManagerService"); try { Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain"); - mPackageManagerService = PackageManagerService.main(mSystemContext, installer, - domainVerificationService, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, - mOnlyCore); + Pair pmsPair = PackageManagerService.main( + mSystemContext, installer, domainVerificationService, + mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); + mPackageManagerService = pmsPair.first; + iPackageManager = pmsPair.second; } finally { Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain"); } @@ -1238,7 +1242,7 @@ public final class SystemServer implements Dumpable { // Now that the package manager has started, register the dex load reporter to capture any // dex files loaded by system server. // These dex files will be optimized by the BackgroundDexOptService. - SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService); + SystemServerDexLoadReporter.configureSystemServerDexReporter(iPackageManager); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); diff --git a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt index dcc461be00151..7017440a86bbd 100644 --- a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt +++ b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt @@ -221,11 +221,14 @@ class PackageManagerComponentLabelIconOverrideTest { @After fun verifyExpectedResult() { assertServiceInitialized() ?: return - if (params.componentName != null) { - val activityInfo = service.getActivityInfo(params.componentName, 0, userId) - if (activityInfo != null) { - assertThat(activityInfo.nonLocalizedLabel).isEqualTo(params.expectedLabel) - assertThat(activityInfo.icon).isEqualTo(params.expectedIcon) + if (params.componentName != null && params.result !is Result.Exception) { + // Suppress so that failures in @After don't override the actual test failure + @Suppress("UNNECESSARY_SAFE_CALL") + service?.let { + val activityInfo = it.snapshotComputer() + .getActivityInfo(params.componentName, 0, userId) + assertThat(activityInfo?.nonLocalizedLabel).isEqualTo(params.expectedLabel) + assertThat(activityInfo?.icon).isEqualTo(params.expectedIcon) } } } @@ -237,9 +240,12 @@ class PackageManagerComponentLabelIconOverrideTest { Result.Changed, Result.ChangedWithoutNotify -> { // Suppress so that failures in @After don't override the actual test failure @Suppress("UNNECESSARY_SAFE_CALL") - val activityInfo = service?.getActivityInfo(params.componentName, 0, userIdDifferent) - assertThat(activityInfo?.nonLocalizedLabel).isEqualTo(DEFAULT_LABEL) - assertThat(activityInfo?.icon).isEqualTo(DEFAULT_ICON) + service?.let { + val activityInfo = it.snapshotComputer() + ?.getActivityInfo(params.componentName, 0, userIdDifferent) + assertThat(activityInfo?.nonLocalizedLabel).isEqualTo(DEFAULT_LABEL) + assertThat(activityInfo?.icon).isEqualTo(DEFAULT_ICON) + } } Result.NotChanged, is Result.Exception -> {} }.run { /*exhaust*/ } diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt index ccfeb4c9df515..fbbb814388f7e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt @@ -74,6 +74,10 @@ class PackageFreezerTest { assertThat(assertFailsWith(exceptionClass, block).message).contains(message) } + private fun checkPackageStartable() { + pms.checkPackageStartable(pms.snapshotComputer(), TEST_PACKAGE, TEST_USER_ID) + } + @Before @Throws(Exception::class) fun setup() { @@ -89,11 +93,11 @@ class PackageFreezerTest { .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON)) assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) { - pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID) + checkPackageStartable() } freezer.close() - pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID) + checkPackageStartable() } @Test @@ -104,16 +108,16 @@ class PackageFreezerTest { .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON)) assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) { - pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID) + checkPackageStartable() } freezer1.close() assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) { - pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID) + checkPackageStartable() } freezer2.close() - pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID) + checkPackageStartable() } @Test @@ -123,13 +127,13 @@ class PackageFreezerTest { .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON)) assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) { - pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID) + checkPackageStartable() } freezer = null System.gc() System.runFinalization() - pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID) + checkPackageStartable() } } diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt index a6c7bfb456be4..13199032a223d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt @@ -107,7 +107,7 @@ class PackageManagerServiceHibernationTests { whenever(appHibernationManager.isHibernatingForUser(TEST_PACKAGE_NAME, TEST_USER_ID)) .thenReturn(true) - pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID) + pm.setPackageStoppedState(pm.snapshotComputer(), TEST_PACKAGE_NAME, false, TEST_USER_ID) TestableLooper.get(this).processAllMessages() @@ -133,7 +133,8 @@ class PackageManagerServiceHibernationTests { .thenReturn(true) try { - pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID) + pm.setPackageStoppedState(pm.snapshotComputer(), TEST_PACKAGE_NAME, false, + TEST_USER_ID) TestableLooper.get(this).processAllMessages() } catch (e: Exception) { Assert.fail("Method throws exception when AppHibernationManager is not ready.\n$e") diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java index 3d21b74825f01..b37e94aaecac6 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java @@ -20,6 +20,10 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -68,12 +72,17 @@ public class PackageInstallerSessionTest { @Mock PackageManagerService mMockPackageManagerInternal; + @Mock + Computer mSnapshot; + @Before public void setUp() throws Exception { mTmpDir = mTemporaryFolder.newFolder("PackageInstallerSessionTest"); mSessionsFile = new AtomicFile( new File(mTmpDir.getAbsolutePath() + "/sessions.xml"), "package-session"); MockitoAnnotations.initMocks(this); + when(mSnapshot.getPackageUid(anyString(), anyLong(), anyInt())).thenReturn(0); + when(mMockPackageManagerInternal.snapshotComputer()).thenReturn(mSnapshot); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java index 0c8394e75fbc2..24ff3f96100a1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java @@ -41,9 +41,11 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; +import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.Presubmit; @@ -58,8 +60,6 @@ import com.android.internal.app.SuspendedAppActivity; import com.android.internal.app.UnlaunchableAppActivity; import com.android.server.LocalServices; import com.android.server.am.ActivityManagerService; -import com.android.server.pm.PackageManagerService; -import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult; import org.junit.After; import org.junit.Before; @@ -113,7 +113,7 @@ public class ActivityStartInterceptorTest { @Mock private KeyguardManager mKeyguardManager; @Mock - private PackageManagerService mPackageManager; + private IPackageManager mPackageManager; @Mock private ActivityManagerInternal mAmInternal; @Mock @@ -126,7 +126,7 @@ public class ActivityStartInterceptorTest { new SparseArray<>(); @Before - public void setUp() { + public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); mService.mAmInternal = mAmInternal; mInterceptor = new ActivityStartInterceptor( @@ -279,7 +279,7 @@ public class ActivityStartInterceptorTest { } @Test - public void testHarmfulAppWarning() { + public void testHarmfulAppWarning() throws RemoteException { // GIVEN the package we're about to launch has a harmful app warning set when(mPackageManager.getHarmfulAppWarning(TEST_PACKAGE_NAME, TEST_USER_ID)) .thenReturn("This app is bad");