summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xapi/system-current.txt4
-rw-r--r--core/java/android/content/om/OverlayManager.java48
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java2
-rw-r--r--services/core/java/com/android/server/om/OverlayActorEnforcer.java5
6 files changed, 54 insertions, 9 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index 6a8f3052787b..800977cfc596 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -2042,8 +2042,8 @@ package android.content.om {
public class OverlayManager {
method @Nullable public android.content.om.OverlayInfo getOverlayInfo(@NonNull String, @NonNull android.os.UserHandle);
method @NonNull @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public java.util.List<android.content.om.OverlayInfo> getOverlayInfosForTarget(@NonNull String, @NonNull android.os.UserHandle);
- method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public void setEnabled(@NonNull String, boolean, @NonNull android.os.UserHandle);
- method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public void setEnabledExclusiveInCategory(@NonNull String, @NonNull android.os.UserHandle);
+ method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public void setEnabled(@NonNull String, boolean, @NonNull android.os.UserHandle) throws java.lang.IllegalStateException, java.lang.SecurityException;
+ method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public void setEnabledExclusiveInCategory(@NonNull String, @NonNull android.os.UserHandle) throws java.lang.IllegalStateException, java.lang.SecurityException;
}
}
diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java
index a2f8886eb7d2..33d17763fb24 100644
--- a/core/java/android/content/om/OverlayManager.java
+++ b/core/java/android/content/om/OverlayManager.java
@@ -22,7 +22,11 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.compat.Compatibility;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.content.Context;
+import android.os.Build;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
@@ -40,6 +44,10 @@ public class OverlayManager {
private final IOverlayManager mService;
private final Context mContext;
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
+ private static final long THROW_SECURITY_EXCEPTIONS = 147340954;
+
/**
* Creates a new instance.
*
@@ -69,6 +77,9 @@ public class OverlayManager {
* @param packageName the name of the overlay package to enable.
* @param user The user for which to change the overlay.
*
+ * @throws SecurityException when caller is not allowed to enable {@param packageName}
+ * @throws IllegalStateException when enabling fails otherwise
+ *
* @hide
*/
@SystemApi
@@ -77,11 +88,13 @@ public class OverlayManager {
"android.permission.INTERACT_ACROSS_USERS_FULL"
})
public void setEnabledExclusiveInCategory(@NonNull final String packageName,
- @NonNull UserHandle user) {
+ @NonNull UserHandle user) throws SecurityException, IllegalStateException {
try {
if (!mService.setEnabledExclusiveInCategory(packageName, user.getIdentifier())) {
throw new IllegalStateException("setEnabledExclusiveInCategory failed");
}
+ } catch (SecurityException e) {
+ rethrowSecurityException(e);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -97,6 +110,9 @@ public class OverlayManager {
* @param enable {@code false} if the overlay should be turned off.
* @param user The user for which to change the overlay.
*
+ * @throws SecurityException when caller is not allowed to enable/disable {@param packageName}
+ * @throws IllegalStateException when enabling/disabling fails otherwise
+ *
* @hide
*/
@SystemApi
@@ -105,15 +121,16 @@ public class OverlayManager {
"android.permission.INTERACT_ACROSS_USERS_FULL"
})
public void setEnabled(@NonNull final String packageName, final boolean enable,
- @NonNull UserHandle user) {
+ @NonNull UserHandle user) throws SecurityException, IllegalStateException {
try {
if (!mService.setEnabled(packageName, enable, user.getIdentifier())) {
throw new IllegalStateException("setEnabled failed");
}
+ } catch (SecurityException e) {
+ rethrowSecurityException(e);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- return;
}
/**
@@ -187,4 +204,29 @@ public class OverlayManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Starting on R, actor enforcement and app visibility changes introduce additional failure
+ * cases, but the SecurityException thrown with these checks is unexpected for existing
+ * consumers of the API.
+ *
+ * The only prior case it would be thrown is with a permission failure, but the calling
+ * application would be able to verify that themselves, and so they may choose to ignore
+ * catching SecurityException when calling these APIs.
+ *
+ * For R, this no longer holds true, and SecurityExceptions can be thrown for any number of
+ * reasons, none of which are exposed to the caller. So for consumers targeting below R,
+ * transform these SecurityExceptions into IllegalStateExceptions, which are a little more
+ * expected to be thrown by the setEnabled APIs.
+ *
+ * This will mask the prior permission exception if it applies, but it's assumed that apps
+ * wouldn't call the APIs without the permission on prior versions, and so it's safe to ignore.
+ */
+ private void rethrowSecurityException(SecurityException e) {
+ if (!Compatibility.isChangeEnabled(THROW_SECURITY_EXCEPTIONS)) {
+ throw new IllegalStateException(e);
+ } else {
+ throw e;
+ }
+ }
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 486386f3d284..107207638205 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -4488,7 +4488,7 @@ public class SettingsProvider extends ContentProvider {
try {
overlayManager.setEnabledExclusiveInCategory(
NAV_BAR_MODE_2BUTTON_OVERLAY, UserHandle.USER_CURRENT);
- } catch (RemoteException e) {
+ } catch (SecurityException | IllegalStateException | RemoteException e) {
throw new IllegalStateException(
"Failed to set nav bar interaction mode overlay");
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
index d6336ed3e18a..826af669cb39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
@@ -387,7 +387,7 @@ public class NavigationModeController implements Dumpable {
Log.d(TAG, "setModeOverlay: overlayPackage=" + overlayPkg
+ " userId=" + userId);
}
- } catch (RemoteException e) {
+ } catch (SecurityException | IllegalStateException | RemoteException e) {
Log.e(TAG, "Failed to enable overlay " + overlayPkg + " for user " + userId);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
index 41e026af7c72..665cb6307b6a 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
@@ -178,7 +178,7 @@ class ThemeOverlayManager {
} else {
mOverlayManager.setEnabled(pkg, false, userHandle);
}
- } catch (IllegalStateException e) {
+ } catch (SecurityException | IllegalStateException e) {
Log.e(TAG,
String.format("setEnabled failed: %s %s %b", pkg, userHandle, enabled), e);
}
diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
index ac3bf9ad5d8a..0a9f923ac817 100644
--- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java
+++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
@@ -43,6 +43,9 @@ import java.util.Map;
*/
public class OverlayActorEnforcer {
+ // By default, the reason is not logged to prevent leaks of why it failed
+ private static final boolean DEBUG_REASON = false;
+
private final VerifyCallback mVerifyCallback;
/**
@@ -92,7 +95,7 @@ public class OverlayActorEnforcer {
throw new SecurityException("UID" + callingUid + " is not allowed to call "
+ methodName + " for "
+ (TextUtils.isEmpty(targetOverlayableName) ? "" : (targetOverlayableName + " in "))
- + overlayInfo.targetPackageName + " because " + actorState
+ + overlayInfo.targetPackageName + (DEBUG_REASON ? (" because " + actorState) : "")
);
}