Not allow shell to dump screen by using ui-automator if...
DISALLOW_DEBUGGING_FEATURES is set

(adb unroot first)
Test: Turn on DISALLOW_DEBUGGING_FEATURES in work profile.
      Can dump personal window + Cannot dump work window by using
      adb shell uiautomator dump
Test: Turn off DISALLOW_DEBUGGING_FEATURES in work profile.
      Can dump window in both profiles
Test: atest CtsAccessibilityServiceTestCases
Test: Enable talkback, try launching a few apps and interact with them.

Fixes: 73147467

Change-Id: I044a1546f9b568b0d19714154d6e7e5ab7232d26
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 8941b49..de112f9 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -853,11 +853,7 @@
             if (mSecurityPolicy.findA11yWindowInfoById(windowId) == null) {
                 return null;
             }
-            IBinder token = mGlobalWindowTokens.get(windowId);
-            if (token != null) {
-                return token;
-            }
-            return getCurrentUserStateLocked().mWindowTokens.get(windowId);
+            return findWindowTokenLocked(windowId);
         }
     }
 
@@ -2527,6 +2523,14 @@
         getInteractionBridge().clearAccessibilityFocusNotLocked(windowId);
     }
 
+    private IBinder findWindowTokenLocked(int windowId) {
+        IBinder token = mGlobalWindowTokens.get(windowId);
+        if (token != null) {
+            return token;
+        }
+        return getCurrentUserStateLocked().mWindowTokens.get(windowId);
+    }
+
     private int findWindowIdLocked(IBinder token) {
         final int globalIndex = mGlobalWindowTokens.indexOfValue(token);
         if (globalIndex >= 0) {
@@ -2986,7 +2990,7 @@
                 // the accessibility layer reports which are windows
                 // that a sighted user can touch.
                 default: {
-                    return isRetrievalAllowingWindow(event.getWindowId());
+                    return isRetrievalAllowingWindowLocked(event.getWindowId());
                 }
             }
         }
@@ -3438,7 +3442,8 @@
 
         public boolean canGetAccessibilityNodeInfoLocked(
                 AbstractAccessibilityServiceConnection service, int windowId) {
-            return canRetrieveWindowContentLocked(service) && isRetrievalAllowingWindow(windowId);
+            return canRetrieveWindowContentLocked(service)
+                    && isRetrievalAllowingWindowLocked(windowId);
         }
 
         public boolean canRetrieveWindowsLocked(AbstractAccessibilityServiceConnection service) {
@@ -3523,17 +3528,40 @@
                     || userId == UserHandle.USER_CURRENT_OR_SELF);
         }
 
-        private boolean isRetrievalAllowingWindow(int windowId) {
+        private boolean isRetrievalAllowingWindowLocked(int windowId) {
             // The system gets to interact with any window it wants.
             if (Binder.getCallingUid() == Process.SYSTEM_UID) {
                 return true;
             }
+            if (Binder.getCallingUid() == Process.SHELL_UID) {
+                if (!isShellAllowedToRetrieveWindowLocked(windowId)) {
+                    return false;
+                }
+            }
             if (windowId == mActiveWindowId) {
                 return true;
             }
             return findA11yWindowInfoById(windowId) != null;
         }
 
+        private boolean isShellAllowedToRetrieveWindowLocked(int windowId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                IBinder windowToken = findWindowTokenLocked(windowId);
+                if (windowToken == null) {
+                    return false;
+                }
+                int userId = mWindowManagerService.getWindowOwnerUserId(windowToken);
+                if (userId == UserHandle.USER_NULL) {
+                    return false;
+                }
+                return !mUserManager.hasUserRestriction(
+                        UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.of(userId));
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
         public AccessibilityWindowInfo findA11yWindowInfoById(int windowId) {
             return mA11yWindowInfoById.get(windowId);
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 6bceda5..6686b80 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -419,4 +419,10 @@
      * @see android.view.IWindowManager#lockNow
      */
     public abstract void lockNow();
+
+    /**
+     * Return the user that owns the given window, {@link android.os.UserHandle#USER_NULL} if
+     * the window token is not found.
+     */
+    public abstract int getWindowOwnerUserId(IBinder windowToken);
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 56b314f..f664ab0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7354,6 +7354,17 @@
         public void lockNow() {
             WindowManagerService.this.lockNow(null);
         }
+
+        @Override
+        public int getWindowOwnerUserId(IBinder token) {
+            synchronized (mWindowMap) {
+                WindowState window = mWindowMap.get(token);
+                if (window != null) {
+                    return UserHandle.getUserId(window.mOwnerUid);
+                }
+                return UserHandle.USER_NULL;
+            }
+        }
     }
 
     void registerAppFreezeListener(AppFreezeListener listener) {