summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Bernardo Rufino <brufino@google.com> 2021-04-06 17:27:14 +0100
committer Bernardo Rufino <brufino@google.com> 2021-04-07 15:26:05 +0100
commit19a613c3da75c7a87bfa221d78e6e3b3dce287b1 (patch)
treeca4d221d53f06cca06340a7944f35d6d142849a5
parent20953edc6f3015c17ddb735e21ccf3df38399cc0 (diff)
Allow accessibility services to send Intent.ACSD
For targetSdk < S. For S, they can use the new GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE action to dismiss the notification shade. Bug: 159334261 Test: Send Intent.ACSD from an a11y service and verify shade is collapsed when targetSdk < S, and exception thrown when targetSdk S+. Change-Id: I0e4be3faef8efa53a0b8a08263e842e0c4b1553e
-rw-r--r--core/java/android/content/Intent.java3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java6
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java31
4 files changed, 35 insertions, 8 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2c77372d6345..2c1c67eb6a42 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -18,6 +18,7 @@ package android.content;
import static android.content.ContentProvider.maybeAddUserId;
+import android.accessibilityservice.AccessibilityService;
import android.annotation.AnyRes;
import android.annotation.BroadcastBehavior;
import android.annotation.IntDef;
@@ -2479,6 +2480,8 @@ public class Intent implements Parcelable, Cloneable {
* (eg. tests) is still able to use the intent. The platform will automatically collapse
* the proper system dialogs in the proper use-cases. For all others, the user is the one in
* control of closing dialogs.
+ *
+ * @see AccessibilityService#GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@RequiresPermission(android.Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS)
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 8e803b3619fb..05d4ba539a98 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1882,12 +1882,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mTempIntArray.add(resolveInfo.serviceInfo.applicationInfo.uid);
}
}
- // Calling out with lock held, but to a lower-level service
+ // Calling out with lock held, but to lower-level services
final AudioManagerInternal audioManager =
LocalServices.getService(AudioManagerInternal.class);
if (audioManager != null) {
audioManager.setAccessibilityServiceUids(mTempIntArray);
}
+ mActivityTaskManagerService.setAccessibilityServiceUids(mTempIntArray);
updateAccessibilityEnabledSettingLocked(userState);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index c09136eac302..aa993bfeaf2e 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -32,6 +32,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.service.voice.IVoiceInteractionSession;
+import android.util.IntArray;
import android.util.proto.ProtoOutputStream;
import android.window.TaskSnapshot;
@@ -222,6 +223,11 @@ public abstract class ActivityTaskManagerInternal {
@Nullable BackgroundActivityStartCallback callback);
/**
+ * Sets the list of UIDs that contain an active accessibility service.
+ */
+ public abstract void setAccessibilityServiceUids(IntArray uids);
+
+ /**
* Start activity {@code intent} without calling user-id check.
*
* - DO NOT call it with the calling UID cleared.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index c8fa50c35baa..7ae42cc9396a 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -214,6 +214,7 @@ import android.telecom.TelecomManager;
import android.text.format.TimeMigrationUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.IntArray;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -677,6 +678,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Nullable
private BackgroundActivityStartCallback mBackgroundActivityStartCallback;
+ private int[] mAccessibilityServiceUids = new int[0];
+
private int mDeviceOwnerUid = Process.INVALID_UID;
private final class SettingObserver extends ContentObserver {
@@ -2990,20 +2993,26 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return true;
}
}
- // This covers the case where the app is displaying some UI on top of the notification shade
- // and wants to start an activity. The app then sends the intent in order to move the
- // notification shade out of the way and show the activity to the user. This is fine since
- // the caller already has privilege to show a visible window on top of the notification
- // shade, so it can already prevent the user from accessing the shade if it wants to.
- // We only allow for targetSdk < S, for S+ we automatically collapse the shade on
- // startActivity() for these apps.
if (!CompatChanges.isChangeEnabled(LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) {
synchronized (mGlobalLock) {
+ // This covers the case where the app is displaying some UI on top of the
+ // notification shade and wants to start an activity. The app then sends the intent
+ // in order to move the notification shade out of the way and show the activity to
+ // the user. This is fine since the caller already has privilege to show a visible
+ // window on top of the notification shade, so it can already prevent the user from
+ // accessing the shade if it wants to. We only allow for targetSdk < S, for S+ we
+ // automatically collapse the shade on startActivity() for these apps.
// It's ok that the owner of the shade is not allowed *per this rule* because it has
// BROADCAST_CLOSE_SYSTEM_DIALOGS (SystemUI), so it would fall into that rule.
if (mRootWindowContainer.hasVisibleWindowAboveButDoesNotOwnNotificationShade(uid)) {
return true;
}
+ // Accessibility services are allowed to send the intent unless they are targeting
+ // S+, in which case they should use {@link AccessibilityService
+ // #GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE} to dismiss the notification shade.
+ if (ArrayUtils.contains(mAccessibilityServiceUids, uid)) {
+ return true;
+ }
}
}
return false;
@@ -5122,12 +5131,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return mVisibleActivityProcessTracker.hasResumedActivity(uid);
}
+ @Override
public void setBackgroundActivityStartCallback(
@Nullable BackgroundActivityStartCallback backgroundActivityStartCallback) {
mBackgroundActivityStartCallback = backgroundActivityStartCallback;
}
@Override
+ public void setAccessibilityServiceUids(IntArray uids) {
+ synchronized (mGlobalLock) {
+ mAccessibilityServiceUids = uids.toArray();
+ }
+ }
+
+ @Override
public int startActivitiesAsPackage(String packageName, @Nullable String featureId,
int userId, Intent[] intents, Bundle bOptions) {
Objects.requireNonNull(intents, "intents");