diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java index 4ccd67dd90034..12ed0e0229c22 100644 --- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java +++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java @@ -398,6 +398,13 @@ public class PackageInfoWithoutStateUtils { assignUserFields(pkg, ai, userId); } + updateApplicationInfo(ai, flags, state); + + return ai; + } + + private static void updateApplicationInfo(ApplicationInfo ai, int flags, + PackageUserState state) { if ((flags & PackageManager.GET_META_DATA) == 0) { ai.metaData = null; } @@ -407,7 +414,7 @@ public class PackageInfoWithoutStateUtils { } // CompatibilityMode is global state. - if (!android.content.pm.PackageParser.sCompatibilityModeEnabled) { + if (!ParsingPackageUtils.sCompatibilityModeEnabled) { ai.disableCompatibilityMode(); } @@ -439,7 +446,37 @@ public class PackageInfoWithoutStateUtils { ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]); ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]); } + } + @Nullable + public static ApplicationInfo generateDelegateApplicationInfo(@Nullable ApplicationInfo ai, + @PackageManager.ApplicationInfoFlags int flags, @NonNull PackageUserState state, + int userId) { + if (ai == null || !checkUseInstalledOrHidden(flags, state, ai)) { + return null; + } + // This is used to return the ResolverActivity or instantAppInstallerActivity; + // we will just always make a copy. + ai = new ApplicationInfo(ai); + ai.initForUser(userId); + ai.icon = (ParsingPackageUtils.sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes + : ai.iconRes; + updateApplicationInfo(ai, flags, state); + return ai; + } + + @Nullable + public static ActivityInfo generateDelegateActivityInfo(@Nullable ActivityInfo a, + @PackageManager.ComponentInfoFlags int flags, @NonNull PackageUserState state, + int userId) { + if (a == null || !checkUseInstalledOrHidden(flags, state, a.applicationInfo)) { + return null; + } + // This is used to return the ResolverActivity or instantAppInstallerActivity; + // we will just always make a copy. + final ActivityInfo ai = new ActivityInfo(a); + ai.applicationInfo = + generateDelegateApplicationInfo(ai.applicationInfo, flags, state, userId); return ai; } @@ -716,6 +753,23 @@ public class PackageInfoWithoutStateUtils { return new Attribution(pa.tag, pa.label); } + private static boolean checkUseInstalledOrHidden(int flags, @NonNull PackageUserState state, + @Nullable ApplicationInfo appInfo) { + // Returns false if the package is hidden system app until installed. + if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0 + && !state.installed + && appInfo != null && appInfo.hiddenUntilInstalled) { + return false; + } + + // If available for the target user, or trying to match uninstalled packages and it's + // a system app. + return state.isAvailable(flags) + || (appInfo != null && appInfo.isSystemApp() + && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0 + || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0)); + } + private static void assignSharedFieldsForComponentInfo(@NonNull ComponentInfo componentInfo, @NonNull ParsedMainComponent mainComponent) { assignSharedFieldsForPackageItemInfo(componentInfo, mainComponent); diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index e96a73342dee9..77a5fbf723238 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -3052,6 +3052,13 @@ public class ParsingPackageUtils { } } + /** + * @hide + */ + public static void setCompatibilityModeEnabled(boolean compatibilityModeEnabled) { + sCompatibilityModeEnabled = compatibilityModeEnabled; + } + /** * @hide */ diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 153d010bdd892..04a5233375e18 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -242,6 +242,7 @@ import android.content.pm.dex.DexMetadataHelper; import android.content.pm.dex.IArtManager; import android.content.pm.overlay.OverlayPaths; import android.content.pm.parsing.ApkLiteParseUtils; +import android.content.pm.parsing.PackageInfoWithoutStateUtils; import android.content.pm.parsing.PackageLite; import android.content.pm.parsing.ParsingPackageUtils; import android.content.pm.parsing.ParsingPackageUtils.ParseFlags; @@ -2625,8 +2626,8 @@ public class PackageManagerService extends IPackageManager.Stub a, flags, ps.readUserState(userId), userId, ps); } if (resolveComponentName().equals(component)) { - return PackageParser.generateActivityInfo( - mResolveActivity, flags, new PackageUserState(), userId); + return PackageInfoWithoutStateUtils.generateDelegateActivityInfo(mResolveActivity, + flags, new PackageUserState(), userId); } return null; } @@ -3276,8 +3277,10 @@ public class PackageManagerService extends IPackageManager.Stub return result; } final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo); - ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo( - instantAppInstallerActivity(), 0, ps.readUserState(userId), userId); + ephemeralInstaller.activityInfo = + PackageInfoWithoutStateUtils.generateDelegateActivityInfo( + instantAppInstallerActivity(), 0 /*flags*/, ps.readUserState(userId), + userId); ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART | IntentFilter.MATCH_ADJUSTMENT_NORMAL; // add a non-generic filter @@ -3360,8 +3363,8 @@ public class PackageManagerService extends IPackageManager.Stub ai.setVersionCode(ps.versionCode); ai.flags = ps.pkgFlags; ai.privateFlags = ps.pkgPrivateFlags; - pi.applicationInfo = - PackageParser.generateApplicationInfo(ai, flags, state, userId); + pi.applicationInfo = PackageInfoWithoutStateUtils.generateDelegateApplicationInfo( + ai, flags, state, userId); if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for [" + ps.name + "]. Provides a minimum info."); @@ -24445,7 +24448,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( mContext.getContentResolver(), android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; - PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); + ParsingPackageUtils.setCompatibilityModeEnabled(compatibilityModeEnabled); if (DEBUG_SETTINGS) { Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); diff --git a/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java b/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java index 94ac9be4af2a2..0f1b14b7fe891 100644 --- a/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java @@ -30,9 +30,9 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.pm.ApplicationInfo; -import android.content.pm.PackageParser; import android.content.pm.PackageUserState; import android.content.pm.parsing.PackageInfoWithoutStateUtils; +import android.content.pm.parsing.ParsingPackageUtils; import android.os.Build; import com.android.server.pm.parsing.pkg.AndroidPackage; @@ -49,7 +49,7 @@ public class CompatibilityModeTest { @Before public void setUp() { - mCompatibilityModeEnabled = PackageParser.sCompatibilityModeEnabled; + mCompatibilityModeEnabled = ParsingPackageUtils.sCompatibilityModeEnabled; mMockAndroidPackage = mock(AndroidPackage.class); mMockUserState = mock(PackageUserState.class); mMockUserState.installed = true; @@ -226,9 +226,9 @@ public class CompatibilityModeTest { } private void setGlobalCompatibilityMode(boolean enabled) { - if (PackageParser.sCompatibilityModeEnabled == enabled) { + if (ParsingPackageUtils.sCompatibilityModeEnabled == enabled) { return; } - PackageParser.setCompatibilityModeEnabled(enabled); + ParsingPackageUtils.setCompatibilityModeEnabled(enabled); } }