Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f2e97e2 authored by Tony Mak's avatar Tony Mak
Browse files

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
parent 3ff20e22
Loading
Loading
Loading
Loading
+36 −8
Original line number Diff line number Diff line
@@ -853,11 +853,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
            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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                // 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 class AccessibilityManagerService extends IAccessibilityManager.Stub

        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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                    || 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);
        }
+6 −0
Original line number Diff line number Diff line
@@ -419,4 +419,10 @@ public abstract class WindowManagerInternal {
     * @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);
}
+11 −0
Original line number Diff line number Diff line
@@ -7354,6 +7354,17 @@ public class WindowManagerService extends IWindowManager.Stub
        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) {