diff options
15 files changed, 227 insertions, 21 deletions
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 47a5db8ea22a..3fdd023a6b68 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -770,6 +770,11 @@ interface IPackageManager { void setSplashScreenTheme(String packageName, String themeName, int userId); + int getUserMinAspectRatio(String packageName, int userId); + + @EnforcePermission("INSTALL_PACKAGES") + void setUserMinAspectRatio(String packageName, int userId, int aspectRatio); + List<String> getMimeGroup(String packageName, String group); boolean isAutoRevokeWhitelisted(String packageName); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 8fafb18393ef..66aadac6295d 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -2342,6 +2342,64 @@ public abstract class PackageManager { */ public static final int INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST = -130; + /** + * App minimum aspect ratio set by the user which will override app-defined aspect ratio. + * + * @hide + */ + @IntDef(prefix = { "USER_MIN_ASPECT_RATIO_" }, value = { + USER_MIN_ASPECT_RATIO_UNSET, + USER_MIN_ASPECT_RATIO_SPLIT_SCREEN, + USER_MIN_ASPECT_RATIO_DISPLAY_SIZE, + USER_MIN_ASPECT_RATIO_4_3, + USER_MIN_ASPECT_RATIO_16_9, + USER_MIN_ASPECT_RATIO_3_2, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface UserMinAspectRatio {} + + /** + * No aspect ratio override has been set by user. + * + * @hide + */ + public static final int USER_MIN_ASPECT_RATIO_UNSET = 0; + + /** + * Aspect ratio override code: user forces app to split screen aspect ratio. This is adjusted to + * half of the screen without the split screen divider. + * + * @hide + */ + public static final int USER_MIN_ASPECT_RATIO_SPLIT_SCREEN = 1; + + /** + * Aspect ratio override code: user forces app to the aspect ratio of the device display size. + * This will be the portrait aspect ratio of the device if the app is portrait or the landscape + * aspect ratio of the device if the app is landscape. + * + * @hide + */ + public static final int USER_MIN_ASPECT_RATIO_DISPLAY_SIZE = 2; + + /** + * Aspect ratio override code: user forces app to 4:3 min aspect ratio + * @hide + */ + public static final int USER_MIN_ASPECT_RATIO_4_3 = 3; + + /** + * Aspect ratio override code: user forces app to 16:9 min aspect ratio + * @hide + */ + public static final int USER_MIN_ASPECT_RATIO_16_9 = 4; + + /** + * Aspect ratio override code: user forces app to 3:2 min aspect ratio + * @hide + */ + public static final int USER_MIN_ASPECT_RATIO_3_2 = 5; + /** @hide */ @IntDef(flag = true, prefix = { "DELETE_" }, value = { DELETE_KEEP_DATA, diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java index 5f52c16d319c..c1d5af589e8c 100644 --- a/services/core/java/com/android/server/pm/DeletePackageHelper.java +++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java @@ -610,7 +610,8 @@ final class DeletePackageHelper { PackageManager.UNINSTALL_REASON_UNKNOWN, null /*harmfulAppWarning*/, null /*splashScreenTheme*/, - 0 /*firstInstallTime*/); + 0 /*firstInstallTime*/, + PackageManager.USER_MIN_ASPECT_RATIO_UNSET); } mPm.mSettings.writeKernelMappingLPr(ps); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index db47306ad58e..2fc22bf79d91 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -30,6 +30,7 @@ import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET; import static android.os.Process.INVALID_UID; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.os.storage.StorageManager.FLAG_STORAGE_CE; @@ -5239,6 +5240,20 @@ public class PackageManagerService implements PackageSender, TestUtilityService } @Override + @PackageManager.UserMinAspectRatio + public int getUserMinAspectRatio(@NonNull String packageName, int userId) { + final Computer snapshot = snapshotComputer(); + final int callingUid = Binder.getCallingUid(); + snapshot.enforceCrossUserPermission( + callingUid, userId, false /* requireFullPermission */, + false /* checkShell */, "getUserMinAspectRatio"); + final PackageStateInternal packageState = snapshot + .getPackageStateForInstalledAndFiltered(packageName, callingUid, userId); + return packageState == null ? USER_MIN_ASPECT_RATIO_UNSET + : packageState.getUserStateOrDefault(userId).getMinAspectRatio(); + } + + @Override public Bundle getSuspendedPackageAppExtras(String packageName, int userId) { final int callingUid = Binder.getCallingUid(); final Computer snapshot = snapshot(); @@ -6201,6 +6216,32 @@ public class PackageManagerService implements PackageSender, TestUtilityService return true; } + @android.annotation.EnforcePermission(android.Manifest.permission.INSTALL_PACKAGES) + @Override + public void setUserMinAspectRatio(@NonNull String packageName, int userId, + @PackageManager.UserMinAspectRatio int aspectRatio) { + setUserMinAspectRatio_enforcePermission(); + final int callingUid = Binder.getCallingUid(); + final Computer snapshot = snapshotComputer(); + snapshot.enforceCrossUserPermission(callingUid, userId, + false /* requireFullPermission */, false /* checkShell */, + "setUserMinAspectRatio"); + enforceOwnerRights(snapshot, packageName, callingUid); + + final PackageStateInternal packageState = snapshot + .getPackageStateForInstalledAndFiltered(packageName, callingUid, userId); + if (packageState == null) { + return; + } + + if (packageState.getUserStateOrDefault(userId).getMinAspectRatio() == aspectRatio) { + return; + } + + commitPackageStateMutation(null, packageName, state -> + state.userState(userId).setMinAspectRatio(aspectRatio)); + } + @Override @SuppressWarnings("GuardedBy") public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) { diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index 24118203bb56..3e9ccac2993a 100644 --- a/services/core/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java @@ -875,7 +875,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal ArraySet<String> enabledComponents, ArraySet<String> disabledComponents, int installReason, int uninstallReason, String harmfulAppWarning, String splashScreenTheme, - long firstInstallTime) { + long firstInstallTime, int aspectRatio) { modifyUserState(userId) .setSuspendParams(suspendParams) .setCeDataInode(ceDataInode) @@ -894,7 +894,8 @@ public class PackageSetting extends SettingBase implements PackageStateInternal .setVirtualPreload(virtualPreload) .setHarmfulAppWarning(harmfulAppWarning) .setSplashScreenTheme(splashScreenTheme) - .setFirstInstallTimeMillis(firstInstallTime); + .setFirstInstallTimeMillis(firstInstallTime) + .setMinAspectRatio(aspectRatio); onChanged(); } @@ -912,7 +913,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal ? null : otherState.getDisabledComponentsNoCopy().untrackedStorage(), otherState.getInstallReason(), otherState.getUninstallReason(), otherState.getHarmfulAppWarning(), otherState.getSplashScreenTheme(), - otherState.getFirstInstallTimeMillis()); + otherState.getFirstInstallTimeMillis(), otherState.getMinAspectRatio()); } WatchedArraySet<String> getEnabledComponents(int userId) { diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index aaf13ebeff2a..532ae718c030 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -351,6 +351,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile private static final String ATTR_VIRTUAL_PRELOAD = "virtual-preload"; private static final String ATTR_HARMFUL_APP_WARNING = "harmful-app-warning"; private static final String ATTR_SPLASH_SCREEN_THEME = "splash-screen-theme"; + private static final String ATTR_MIN_ASPECT_RATIO = "min-aspect-ratio"; private static final String ATTR_PACKAGE_NAME = "packageName"; private static final String ATTR_BUILD_FINGERPRINT = "buildFingerprint"; @@ -1122,7 +1123,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile PackageManager.UNINSTALL_REASON_UNKNOWN, null /*harmfulAppWarning*/, null /*splashscreenTheme*/, - 0 /*firstInstallTime*/ + 0 /*firstInstallTime*/, + PackageManager.USER_MIN_ASPECT_RATIO_UNSET ); } } @@ -1776,7 +1778,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile PackageManager.UNINSTALL_REASON_UNKNOWN, null /*harmfulAppWarning*/, null /* splashScreenTheme*/, - 0 /*firstInstallTime*/ + 0 /*firstInstallTime*/, + PackageManager.USER_MIN_ASPECT_RATIO_UNSET ); } return; @@ -1871,6 +1874,9 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile ATTR_SPLASH_SCREEN_THEME); final long firstInstallTime = parser.getAttributeLongHex(null, ATTR_FIRST_INSTALL_TIME, 0); + final int minAspectRatio = parser.getAttributeInt(null, + ATTR_MIN_ASPECT_RATIO, + PackageManager.USER_MIN_ASPECT_RATIO_UNSET); ArraySet<String> enabledComponents = null; ArraySet<String> disabledComponents = null; @@ -1947,7 +1953,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile enabledCaller, enabledComponents, disabledComponents, installReason, uninstallReason, harmfulAppWarning, splashScreenTheme, firstInstallTime != 0 ? firstInstallTime : - origFirstInstallTimes.getOrDefault(name, 0L)); + origFirstInstallTimes.getOrDefault(name, 0L), + minAspectRatio); mDomainVerificationManager.setLegacyUserState(name, userId, verifState); } else if (tagName.equals("preferred-activities")) { @@ -2242,6 +2249,11 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile serializer.attribute(null, ATTR_SPLASH_SCREEN_THEME, ustate.getSplashScreenTheme()); } + if (ustate.getMinAspectRatio() + != PackageManager.USER_MIN_ASPECT_RATIO_UNSET) { + serializer.attributeInt(null, ATTR_MIN_ASPECT_RATIO, + ustate.getMinAspectRatio()); + } if (ustate.isSuspended()) { for (int i = 0; i < ustate.getSuspendParams().size(); i++) { final String suspendingPackage = ustate.getSuspendParams().keyAt(i); diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java index 91a25db3710e..3d056e89ba78 100644 --- a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java +++ b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java @@ -377,6 +377,8 @@ public class PackageStateImpl implements PackageState { private final int mUninstallReason; @Nullable private final String mSplashScreenTheme; + @PackageManager.UserMinAspectRatio + private final int mMinAspectRatio; private final long mFirstInstallTimeMillis; private UserStateImpl(@NonNull PackageUserState userState) { @@ -392,6 +394,7 @@ public class PackageStateImpl implements PackageState { mSharedLibraryOverlayPaths = userState.getSharedLibraryOverlayPaths(); mUninstallReason = userState.getUninstallReason(); mSplashScreenTheme = userState.getSplashScreenTheme(); + mMinAspectRatio = userState.getMinAspectRatio(); setBoolean(Booleans.HIDDEN, userState.isHidden()); setBoolean(Booleans.INSTALLED, userState.isInstalled()); setBoolean(Booleans.INSTANT_APP, userState.isInstantApp()); @@ -543,6 +546,11 @@ public class PackageStateImpl implements PackageState { } @DataClass.Generated.Member + public @PackageManager.UserMinAspectRatio int getMinAspectRatio() { + return mMinAspectRatio; + } + + @DataClass.Generated.Member public long getFirstInstallTimeMillis() { return mFirstInstallTimeMillis; } @@ -554,10 +562,10 @@ public class PackageStateImpl implements PackageState { } @DataClass.Generated( - time = 1671671043891L, + time = 1687938966108L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java", - inputSignatures = "private int mBooleans\nprivate final long mCeDataInode\nprivate final @android.annotation.NonNull android.util.ArraySet<java.lang.String> mDisabledComponents\nprivate final @android.content.pm.PackageManager.DistractionRestriction int mDistractionFlags\nprivate final @android.annotation.NonNull android.util.ArraySet<java.lang.String> mEnabledComponents\nprivate final int mEnabledState\nprivate final @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate final @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate final @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate final @android.annotation.NonNull android.content.pm.overlay.OverlayPaths mOverlayPaths\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate final @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate final @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate final long mFirstInstallTimeMillis\npublic static com.android.server.pm.pkg.PackageUserState copy(com.android.server.pm.pkg.PackageUserState)\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\npublic @java.lang.Override boolean isHidden()\npublic @java.lang.Override boolean isInstalled()\npublic @java.lang.Override boolean isInstantApp()\npublic @java.lang.Override boolean isNotLaunched()\npublic @java.lang.Override boolean isStopped()\npublic @java.lang.Override boolean isSuspended()\npublic @java.lang.Override boolean isVirtualPreload()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\nclass UserStateImpl extends java.lang.Object implements [com.android.server.pm.pkg.PackageUserState]\nprivate static final int HIDDEN\nprivate static final int INSTALLED\nprivate static final int INSTANT_APP\nprivate static final int NOT_LAUNCHED\nprivate static final int STOPPED\nprivate static final int SUSPENDED\nprivate static final int VIRTUAL_PRELOAD\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false)") + inputSignatures = "private int mBooleans\nprivate final long mCeDataInode\nprivate final @android.annotation.NonNull android.util.ArraySet<java.lang.String> mDisabledComponents\nprivate final @android.content.pm.PackageManager.DistractionRestriction int mDistractionFlags\nprivate final @android.annotation.NonNull android.util.ArraySet<java.lang.String> mEnabledComponents\nprivate final int mEnabledState\nprivate final @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate final @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate final @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate final @android.annotation.NonNull android.content.pm.overlay.OverlayPaths mOverlayPaths\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate final @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate final @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate final @android.content.pm.PackageManager.UserMinAspectRatio int mMinAspectRatio\nprivate final long mFirstInstallTimeMillis\npublic static com.android.server.pm.pkg.PackageUserState copy(com.android.server.pm.pkg.PackageUserState)\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\npublic @java.lang.Override boolean isHidden()\npublic @java.lang.Override boolean isInstalled()\npublic @java.lang.Override boolean isInstantApp()\npublic @java.lang.Override boolean isNotLaunched()\npublic @java.lang.Override boolean isStopped()\npublic @java.lang.Override boolean isSuspended()\npublic @java.lang.Override boolean isVirtualPreload()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\nclass UserStateImpl extends java.lang.Object implements [com.android.server.pm.pkg.PackageUserState]\nprivate static final int HIDDEN\nprivate static final int INSTALLED\nprivate static final int INSTANT_APP\nprivate static final int NOT_LAUNCHED\nprivate static final int STOPPED\nprivate static final int SUSPENDED\nprivate static final int VIRTUAL_PRELOAD\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false)") @Deprecated private void __metadata() {} diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserState.java b/services/core/java/com/android/server/pm/pkg/PackageUserState.java index 2048d651e11e..f75d214c5128 100644 --- a/services/core/java/com/android/server/pm/pkg/PackageUserState.java +++ b/services/core/java/com/android/server/pm/pkg/PackageUserState.java @@ -217,4 +217,12 @@ public interface PackageUserState { */ @Nullable String getSplashScreenTheme(); + + /** + * @return the min aspect ratio setting of the package which by default is unset + * unless it has been set by the user + * @hide + */ + @PackageManager.UserMinAspectRatio + int getMinAspectRatio(); } diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java index 73fb67298aec..1fb12a8ce218 100644 --- a/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java +++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java @@ -136,6 +136,11 @@ class PackageUserStateDefault implements PackageUserStateInternal { } @Override + public @PackageManager.UserMinAspectRatio int getMinAspectRatio() { + return PackageManager.USER_MIN_ASPECT_RATIO_UNSET; + } + + @Override public long getFirstInstallTimeMillis() { return 0; } diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java index e8e2d4179326..d911ac1cfcd8 100644 --- a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java +++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java @@ -83,6 +83,9 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt @Nullable private String mSplashScreenTheme; + @PackageManager.UserMinAspectRatio + private int mMinAspectRatio = PackageManager.USER_MIN_ASPECT_RATIO_UNSET; + /** * Suspending package to suspend params */ @@ -146,6 +149,7 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt mHarmfulAppWarning = other.mHarmfulAppWarning; mLastDisableAppCaller = other.mLastDisableAppCaller; mSplashScreenTheme = other.mSplashScreenTheme; + mMinAspectRatio = other.mMinAspectRatio; mSuspendParams = other.mSuspendParams == null ? null : other.mSuspendParams.snapshot(); mComponentLabelIconOverrideMap = other.mComponentLabelIconOverrideMap == null ? null : other.mComponentLabelIconOverrideMap.snapshot(); @@ -508,6 +512,19 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt } /** + * Sets user min aspect ratio override value + * @see PackageManager.UserMinAspectRatio + */ + public @NonNull PackageUserStateImpl setMinAspectRatio( + @PackageManager.UserMinAspectRatio int value) { + mMinAspectRatio = value; + com.android.internal.util.AnnotationValidations.validate( + PackageManager.UserMinAspectRatio.class, null, mMinAspectRatio); + onChanged(); + return this; + } + + /** * Suspending package to suspend params */ public @NonNull PackageUserStateImpl setSuspendParams( @@ -679,6 +696,11 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt return mSplashScreenTheme; } + @DataClass.Generated.Member + public @PackageManager.UserMinAspectRatio int getMinAspectRatio() { + return mMinAspectRatio; + } + /** * Suspending package to suspend params */ @@ -766,6 +788,7 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt && Objects.equals(mOverlayPaths, that.mOverlayPaths) && Objects.equals(mSharedLibraryOverlayPaths, that.mSharedLibraryOverlayPaths) && Objects.equals(mSplashScreenTheme, that.mSplashScreenTheme) + && mMinAspectRatio == that.mMinAspectRatio && Objects.equals(mSuspendParams, that.mSuspendParams) && Objects.equals(mComponentLabelIconOverrideMap, that.mComponentLabelIconOverrideMap) && mFirstInstallTimeMillis == that.mFirstInstallTimeMillis @@ -798,6 +821,7 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt _hash = 31 * _hash + Objects.hashCode(mOverlayPaths); _hash = 31 * _hash + Objects.hashCode(mSharedLibraryOverlayPaths); _hash = 31 * _hash + Objects.hashCode(mSplashScreenTheme); + _hash = 31 * _hash + mMinAspectRatio; _hash = 31 * _hash + Objects.hashCode(mSuspendParams); _hash = 31 * _hash + Objects.hashCode(mComponentLabelIconOverrideMap); _hash = 31 * _hash + Long.hashCode(mFirstInstallTimeMillis); @@ -807,10 +831,10 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt } @DataClass.Generated( - time = 1686952839807L, + time = 1687938397579L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java", - inputSignatures = "protected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mDisabledComponentsWatched\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mEnabledComponentsWatched\nprivate long mCeDataInode\nprivate boolean mInstalled\nprivate boolean mStopped\nprivate boolean mNotLaunched\nprivate boolean mHidden\nprivate int mDistractionFlags\nprivate boolean mInstantApp\nprivate boolean mVirtualPreload\nprivate @android.content.pm.PackageManager.EnabledState int mEnabledState\nprivate @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate @android.annotation.Nullable android.content.pm.overlay.OverlayPaths mOverlayPaths\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams> mSuspendParams\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>> mComponentLabelIconOverrideMap\nprivate @android.annotation.CurrentTimeMillisLong long mFirstInstallTimeMillis\nprivate @android.annotation.Nullable com.android.server.utils.Watchable mWatchable\nfinal @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> mSnapshot\nprivate com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> makeCache()\nprivate void onChanged()\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserStateImpl snapshot()\npublic @android.annotation.Nullable boolean setOverlayPaths(android.content.pm.overlay.OverlayPaths)\npublic boolean setSharedLibraryOverlayPaths(java.lang.String,android.content.pm.overlay.OverlayPaths)\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponentsNoCopy()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponentsNoCopy()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getDisabledComponents()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getEnabledComponents()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer)\npublic void resetOverrideComponentLabelIcon()\npublic @android.annotation.Nullable android.util.Pair<java.lang.String,java.lang.Integer> getOverrideLabelIconForComponent(android.content.ComponentName)\npublic @java.lang.Override boolean isSuspended()\npublic com.android.server.pm.pkg.PackageUserStateImpl putSuspendParams(java.lang.String,com.android.server.pm.pkg.SuspendParams)\npublic com.android.server.pm.pkg.PackageUserStateImpl removeSuspension(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setCeDataInode(long)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstalled(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setStopped(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setNotLaunched(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHidden(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDistractionFlags(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstantApp(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setVirtualPreload(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setUninstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHarmfulAppWarning(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setLastDisableAppCaller(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSharedLibraryOverlayPaths(android.util.ArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSplashScreenTheme(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSuspendParams(android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setComponentLabelIconOverrideMap(android.util.ArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setFirstInstallTimeMillis(long)\npublic @android.annotation.NonNull @java.lang.Override java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> getSharedLibraryOverlayPaths()\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setWatchable(com.android.server.utils.Watchable)\nprivate boolean watchableEquals(com.android.server.utils.Watchable)\nprivate int watchableHashCode()\nprivate boolean snapshotEquals(com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl>)\nprivate int snapshotHashCode()\nclass PackageUserStateImpl extends com.android.server.utils.WatchableImpl implements [com.android.server.pm.pkg.PackageUserStateInternal, com.android.server.utils.Snappable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false, genEqualsHashCode=true)") + inputSignatures = "protected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mDisabledComponentsWatched\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mEnabledComponentsWatched\nprivate long mCeDataInode\nprivate boolean mInstalled\nprivate boolean mStopped\nprivate boolean mNotLaunched\nprivate boolean mHidden\nprivate int mDistractionFlags\nprivate boolean mInstantApp\nprivate boolean mVirtualPreload\nprivate @android.content.pm.PackageManager.EnabledState int mEnabledState\nprivate @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate @android.annotation.Nullable android.content.pm.overlay.OverlayPaths mOverlayPaths\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate @android.content.pm.PackageManager.UserMinAspectRatio int mMinAspectRatio\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams> mSuspendParams\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>> mComponentLabelIconOverrideMap\nprivate @android.annotation.CurrentTimeMillisLong long mFirstInstallTimeMillis\nprivate @android.annotation.Nullable com.android.server.utils.Watchable mWatchable\nfinal @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> mSnapshot\nprivate com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> makeCache()\nprivate void onChanged()\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserStateImpl snapshot()\npublic @android.annotation.Nullable boolean setOverlayPaths(android.content.pm.overlay.OverlayPaths)\npublic boolean setSharedLibraryOverlayPaths(java.lang.String,android.content.pm.overlay.OverlayPaths)\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponentsNoCopy()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponentsNoCopy()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getDisabledComponents()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getEnabledComponents()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer)\npublic void resetOverrideComponentLabelIcon()\npublic @android.annotation.Nullable android.util.Pair<java.lang.String,java.lang.Integer> getOverrideLabelIconForComponent(android.content.ComponentName)\npublic @java.lang.Override boolean isSuspended()\npublic com.android.server.pm.pkg.PackageUserStateImpl putSuspendParams(java.lang.String,com.android.server.pm.pkg.SuspendParams)\npublic com.android.server.pm.pkg.PackageUserStateImpl removeSuspension(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setCeDataInode(long)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstalled(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setStopped(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setNotLaunched(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHidden(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDistractionFlags(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstantApp(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setVirtualPreload(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setUninstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHarmfulAppWarning(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setLastDisableAppCaller(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSharedLibraryOverlayPaths(android.util.ArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSplashScreenTheme(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setMinAspectRatio(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSuspendParams(android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setComponentLabelIconOverrideMap(android.util.ArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setFirstInstallTimeMillis(long)\npublic @android.annotation.NonNull @java.lang.Override java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> getSharedLibraryOverlayPaths()\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setWatchable(com.android.server.utils.Watchable)\nprivate boolean watchableEquals(com.android.server.utils.Watchable)\nprivate int watchableHashCode()\nprivate boolean snapshotEquals(com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl>)\nprivate int snapshotHashCode()\nclass PackageUserStateImpl extends com.android.server.utils.WatchableImpl implements [com.android.server.pm.pkg.PackageUserStateInternal, com.android.server.utils.Snappable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false, genEqualsHashCode=true)") @Deprecated private void __metadata() {} diff --git a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java index 8125b0f662aa..8430cf7a0d11 100644 --- a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java +++ b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java @@ -439,6 +439,16 @@ public class PackageStateMutator { } return null; } + + @NonNull + @Override + public PackageUserStateWrite setMinAspectRatio( + @PackageManager.UserMinAspectRatio int aspectRatio) { + if (mUserState != null) { + mUserState.setMinAspectRatio(aspectRatio); + } + return this; + } } } } diff --git a/services/core/java/com/android/server/pm/pkg/mutate/PackageUserStateWrite.java b/services/core/java/com/android/server/pm/pkg/mutate/PackageUserStateWrite.java index 11d6d97d3920..0c6c6723b79b 100644 --- a/services/core/java/com/android/server/pm/pkg/mutate/PackageUserStateWrite.java +++ b/services/core/java/com/android/server/pm/pkg/mutate/PackageUserStateWrite.java @@ -22,6 +22,7 @@ import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.overlay.OverlayPaths; +import com.android.server.pm.pkg.PackageUserStateImpl; import com.android.server.pm.pkg.SuspendParams; public interface PackageUserStateWrite { @@ -68,4 +69,8 @@ public interface PackageUserStateWrite { @NonNull PackageUserStateWrite setComponentLabelIcon(@NonNull ComponentName componentName, @Nullable String nonLocalizedLabel, @Nullable Integer icon); + + /** @see PackageUserStateImpl#setMinAspectRatio(int) */ + @NonNull + PackageUserStateWrite setMinAspectRatio(@PackageManager.UserMinAspectRatio int aspectRatio); } diff --git a/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java index e33ca7775e22..b7a0cf389396 100644 --- a/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java +++ b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java @@ -138,6 +138,14 @@ public class CrossUserPackageVisibilityTests { } @Test + public void testGetUserMinAspectRatio_withCrossUserId() { + final int crossUserId = UserHandle.myUserId() + 1; + assertThrows(SecurityException.class, + () -> mIPackageManager.getUserMinAspectRatio( + mInstrumentation.getContext().getPackageName(), crossUserId)); + } + + @Test public void testIsPackageSignedByKeySet_cannotDetectCrossUserPkg() throws Exception { final KeySet keySet = mIPackageManager.getSigningKeySet(mContext.getPackageName()); assertThrows(IllegalArgumentException.class, diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerServiceTest.java index 435f0d7f5f15..a805e5c9f87e 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerServiceTest.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerServiceTest.java @@ -20,6 +20,7 @@ import static com.android.compatibility.common.util.ShellUtils.runShellCommand; import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import static java.lang.reflect.Modifier.isFinal; @@ -138,7 +139,7 @@ public class PackageManagerServiceTest { .setSecondaryCpuAbiString("secondaryCpuAbiString") .setCpuAbiOverrideString("cpuAbiOverrideString") .build(); - pri.populateUsers(new int[] { + pri.populateUsers(new int[]{ 1, 2, 3, 4, 5 }, setting); Assert.assertNotNull(pri.mBroadcastUsers); @@ -150,7 +151,7 @@ public class PackageManagerServiceTest { pri.mBroadcastUsers = null; final int EXCLUDED_USER_ID = 4; setting.setInstantApp(true, EXCLUDED_USER_ID); - pri.populateUsers(new int[] { + pri.populateUsers(new int[]{ 1, 2, 3, EXCLUDED_USER_ID, 5 }, setting); Assert.assertNotNull(pri.mBroadcastUsers); @@ -164,8 +165,8 @@ public class PackageManagerServiceTest { @Test public void testPartitions() { - String[] partitions = { "system", "vendor", "odm", "oem", "product", "system_ext" }; - String[] appdir = { "app", "priv-app" }; + String[] partitions = {"system", "vendor", "odm", "oem", "product", "system_ext"}; + String[] appdir = {"app", "priv-app"}; for (int i = 0; i < partitions.length; i++) { final ScanPartition scanPartition = PackageManagerService.SYSTEM_PARTITIONS.get(i); @@ -425,10 +426,10 @@ public class PackageManagerServiceTest { private String displayName(Method m) { String r = m.getName(); String p = Arrays.toString(m.getGenericParameterTypes()) - .replaceAll("([a-zA-Z0-9]+\\.)+", "") - .replace("class ", "") - .replaceAll("^\\[", "(") - .replaceAll("\\]$", ")"); + .replaceAll("([a-zA-Z0-9]+\\.)+", "") + .replace("class ", "") + .replaceAll("^\\[", "(") + .replaceAll("\\]$", ")"); return r + p; } @@ -612,4 +613,22 @@ public class PackageManagerServiceTest { runShellCommand("pm uninstall " + TEST_PKG_NAME); } } + + @Test + public void testSetUserMinAspectRatio_samePackage_succeeds() throws Exception { + mIPackageManager.setUserMinAspectRatio(PACKAGE_NAME, UserHandle.myUserId(), + PackageManager.USER_MIN_ASPECT_RATIO_UNSET); + // Invoking setUserMinAspectRatio on the same package shouldn't get any exception. + } + + @Test + public void testSetUserMinAspectRatio_differentPackage_fails() { + final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); + runShellCommand("pm install " + testApk); + assertThrows(SecurityException.class, () -> { + mIPackageManager.setUserMinAspectRatio(TEST_PKG_NAME, UserHandle.myUserId(), + PackageManager.USER_MIN_ASPECT_RATIO_UNSET); + }); + runShellCommand("pm uninstall " + TEST_PKG_NAME); + } } diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java index 836f8581e8eb..16fb012b2f40 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -971,7 +971,7 @@ public class PackageManagerSettingsTests { origPkgSetting01.setUserState(0, 100, 1, true, false, false, false, 0, null, false, false, "lastDisabledCaller", new ArraySet<>(new String[]{"enabledComponent1"}), new ArraySet<>(new String[]{"disabledComponent1"}), 0, 0, "harmfulAppWarning", - "splashScreenTheme", 1000L); + "splashScreenTheme", 1000L, PackageManager.USER_MIN_ASPECT_RATIO_UNSET); final PersistableBundle appExtras1 = createPersistableBundle( PACKAGE_NAME_1, 1L, 0.01, true, "appString1"); final PersistableBundle launcherExtras1 = createPersistableBundle( @@ -1638,7 +1638,8 @@ public class PackageManagerSettingsTests { : oldUserState.getSharedLibraryOverlayPaths() == null) && userState.getSplashScreenTheme().equals( oldUserState.getSplashScreenTheme()) - && userState.getUninstallReason() == oldUserState.getUninstallReason(); + && userState.getUninstallReason() == oldUserState.getUninstallReason() + && userState.getMinAspectRatio() == oldUserState.getMinAspectRatio(); } private SharedUserSetting createSharedUserSetting(Settings settings, String userName, |