diff options
6 files changed, 77 insertions, 14 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index fb2b9e1e05fb..054c0c96b5d7 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1560,6 +1560,7 @@ package android.content.pm { method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method public abstract boolean arePermissionsIndividuallyControlled(); method public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(String); + method public boolean getAppDetailsActivityEnabled(@NonNull String); method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.pm.ApplicationInfo getApplicationInfoAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method @NonNull public android.content.pm.dex.ArtManager getArtManager(); method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int); @@ -1586,6 +1587,7 @@ package android.content.pm { method @Deprecated public void replacePreferredActivity(@NonNull android.content.IntentFilter, int, @NonNull java.util.List<android.content.ComponentName>, @NonNull android.content.ComponentName); method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method public void sendDeviceCustomizationReadyBroadcast(); + method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public void setAppDetailsActivityEnabled(@NonNull String, boolean); method @RequiresPermission(allOf={android.Manifest.permission.SET_PREFERRED_APPLICATIONS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public abstract boolean setDefaultBrowserPackageNameAsUser(String, int); method @NonNull @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setDistractingPackageRestrictions(@NonNull String[], int); method @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public void setHarmfulAppWarning(@NonNull String, @Nullable CharSequence); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 98032dc3d297..3372e4124da6 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2467,6 +2467,33 @@ public class ApplicationPackageManager extends PackageManager { } @Override + public void setAppDetailsActivityEnabled(String packageName, boolean enabled) { + try { + ComponentName componentName = new ComponentName(packageName, + PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME); + mPM.setComponentEnabledSetting(componentName, enabled + ? PackageManager.COMPONENT_ENABLED_STATE_DEFAULT + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP, getUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @Override + public boolean getAppDetailsActivityEnabled(String packageName) { + try { + ComponentName componentName = new ComponentName(packageName, + PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME); + int state = mPM.getComponentEnabledSetting(componentName, getUserId()); + return state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED + || state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @Override public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) { try { diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 3ea78df6ae39..592280a947d3 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -33,6 +33,7 @@ import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.annotation.XmlRes; import android.app.ActivityManager; +import android.app.AppDetailsActivity; import android.app.PackageDeleteObserver; import android.app.PackageInstallObserver; import android.app.admin.DevicePolicyManager; @@ -3025,6 +3026,13 @@ public abstract class PackageManager { public static final int MASK_PERMISSION_FLAGS = 0xFF; /** + * Injected activity in app that forwards user to setting activity of that app. + * + * @hide + */ + public static final String APP_DETAILS_ACTIVITY_CLASS_NAME = AppDetailsActivity.class.getName(); + + /** * This is a library that contains components apps can invoke. For * example, a services for apps to bind to, or standard chooser UI, * etc. This library is versioned and backwards compatible. Clients @@ -5785,6 +5793,37 @@ public abstract class PackageManager { @NonNull ComponentName componentName); /** + * Set the enabled setting for a package app settings activity. + * + * @param packageName The package name of the app + * @param enabled The new enabled state for app details activity + * + * @hide + */ + @RequiresPermission(value = android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, + conditional = true) + @SystemApi + public void setAppDetailsActivityEnabled(@NonNull String packageName, boolean enabled) { + throw new UnsupportedOperationException( + "setAppDetailsActivityEnabled not implemented"); + } + + + /** + * Return the enabled setting for a package app settings activity. + * + * @param packageName The package name of the app + * @return Returns the current enabled state for app settings activity. + * + * @hide + */ + @SystemApi + public boolean getAppDetailsActivityEnabled(@NonNull String packageName) { + throw new UnsupportedOperationException( + "getAppDetailsActivityEnabled not implemented"); + } + + /** * Set the enabled setting for an application * This setting will override any enabled state which may have been set by the application in * its manifest. It also overrides the enabled state set in the manifest for any of the diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 0f67262bf901..d7ca757d8025 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -48,7 +48,6 @@ import android.annotation.Nullable; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityTaskManager; -import android.app.AppDetailsActivity; import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; @@ -4311,7 +4310,7 @@ public class PackageParser { } else { String outInfoName = buildClassName(owner.applicationInfo.packageName, name, outError); - if (AppDetailsActivity.class.getName().equals(outInfoName)) { + if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(outInfoName)) { outError[0] = tag + " invalid android:name"; return false; } @@ -4364,13 +4363,14 @@ public class PackageParser { boolean hardwareAccelerated) { // Build custom App Details activity info instead of parsing it from xml - Activity a = new Activity(owner, AppDetailsActivity.class.getName(), new ActivityInfo()); + Activity a = new Activity(owner, PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME, + new ActivityInfo()); a.owner = owner; a.setPackageName(owner.packageName); a.info.theme = android.R.style.Theme_NoDisplay; a.info.exported = true; - a.info.name = AppDetailsActivity.class.getName(); + a.info.name = PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME; a.info.processName = owner.applicationInfo.processName; a.info.uiOptions = a.info.applicationInfo.uiOptions; a.info.taskAffinity = buildTaskAffinityName(owner.packageName, owner.packageName, diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 62c4815a7de0..9e9128430e01 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; -import android.app.AppDetailsActivity; import android.app.AppGlobals; import android.app.IApplicationThread; import android.app.PendingIntent; @@ -367,7 +366,8 @@ public class LauncherAppsService extends SystemService { private ResolveInfo getHiddenAppActivityInfo(String packageName, int callingUid, UserHandle user) { Intent intent = new Intent(); - intent.setComponent(new ComponentName(packageName, AppDetailsActivity.class.getName())); + intent.setComponent(new ComponentName(packageName, + PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME)); final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); List<ResolveInfo> apps = pmInt.queryIntentActivities(intent, diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 61a1a2f81101..9f7280c10c6e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -121,7 +121,6 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; -import android.app.AppDetailsActivity; import android.app.AppOpsManager; import android.app.BroadcastOptions; import android.app.IActivityManager; @@ -20239,13 +20238,9 @@ public class PackageManagerService extends IPackageManager.Stub } // Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden // app details activity - if (AppDetailsActivity.class.getName().equals(className)) { - if (mContext.checkCallingOrSelfPermission( - android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE) - != PackageManager.PERMISSION_GRANTED) { - Slog.e(TAG, "Cannot disable a protected component: " + packageName); - return; - } + if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className) + && !allowedByPermission) { + throw new SecurityException("Cannot disable a system-generated component"); } synchronized (mPackages) { |