Merge "DozeScrimController: Fix tight-posting bug" into oc-mr1-dev
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 68fb7bc..c8d9839 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -262,4 +262,10 @@
* Clears the previously saved activity manager ANR state.
*/
public abstract void clearSavedANRState();
+
+ /**
+ * Set focus on an activity.
+ * @param token The IApplicationToken for the activity
+ */
+ public abstract void setFocusedActivity(IBinder token);
}
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index 95a6394..bb9e391 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -41,6 +41,7 @@
public int layer;
public IBinder token;
public IBinder parentToken;
+ public IBinder activityToken;
public boolean focused;
public final Rect boundsInScreen = new Rect();
public List<IBinder> childTokens;
@@ -66,6 +67,7 @@
window.layer = other.layer;
window.token = other.token;
window.parentToken = other.parentToken;
+ window.activityToken = other.activityToken;
window.focused = other.focused;
window.boundsInScreen.set(other.boundsInScreen);
window.title = other.title;
@@ -99,6 +101,7 @@
parcel.writeInt(layer);
parcel.writeStrongBinder(token);
parcel.writeStrongBinder(parentToken);
+ parcel.writeStrongBinder(activityToken);
parcel.writeInt(focused ? 1 : 0);
boundsInScreen.writeToParcel(parcel, flags);
parcel.writeCharSequence(title);
@@ -135,6 +138,7 @@
layer = parcel.readInt();
token = parcel.readStrongBinder();
parentToken = parcel.readStrongBinder();
+ activityToken = parcel.readStrongBinder();
focused = (parcel.readInt() == 1);
boundsInScreen.readFromParcel(parcel);
title = parcel.readCharSequence();
@@ -155,6 +159,7 @@
layer = 0;
token = null;
parentToken = null;
+ activityToken = null;
focused = false;
boundsInScreen.setEmpty();
if (childTokens != null) {
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 9b2bffd..340b2e1 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2051,4 +2051,10 @@
<!-- Prompt to turn off data usage [CHAR LIMIT=NONE] -->
<string name="data_usage_disable_mobile" msgid="8656552431969276305">Turn off mobile data?</string>
+ <!-- Warning shown when user input has been blocked due to another app overlaying screen
+ content. Since we don't know what the app is showing on top of the input target, we
+ can't verify user consent. [CHAR LIMIT=NONE] -->
+ <string name="touch_filtered_warning">Because an app is obscuring a permission request, Settings
+ can’t verify your response.</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
index f5447a2..70efe5c 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -31,8 +31,12 @@
import android.os.SystemProperties;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
import android.widget.CheckBox;
+import android.widget.Toast;
import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;
@@ -48,6 +52,9 @@
@Override
public void onCreate(Bundle icicle) {
+ Window window = getWindow();
+ window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+
super.onCreate(icicle);
if (SystemProperties.getInt("service.adb.tcp.port", 0) == 0) {
@@ -79,6 +86,29 @@
ap.mView = checkbox;
setupAlert();
+
+ // adding touch listener on affirmative button - checks if window is obscured
+ // if obscured, do not let user give permissions (could be tapjacking involved)
+ final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {
+ // Filter obscured touches by consuming them.
+ if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)
+ || ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ Toast.makeText(v.getContext(),
+ R.string.touch_filtered_warning,
+ Toast.LENGTH_SHORT).show();
+ }
+ return true;
+ }
+ return false;
+ };
+ mAlert.getButton(BUTTON_POSITIVE).setOnTouchListener(filterTouchListener);
+
+ }
+
+ @Override
+ public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
+ super.onWindowAttributesChanged(params);
}
private class UsbDisconnectedReceiver extends BroadcastReceiver {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index a59844d..a97e16b 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -19,6 +19,8 @@
import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
import android.Manifest;
import android.accessibilityservice.AccessibilityService;
@@ -27,6 +29,7 @@
import android.accessibilityservice.IAccessibilityServiceClient;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.annotation.NonNull;
+import android.app.ActivityManagerInternal;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.StatusBarManager;
@@ -847,7 +850,7 @@
if (resolvedUserId != mCurrentUserId) {
return null;
}
- if (mSecurityPolicy.findWindowById(windowId) == null) {
+ if (mSecurityPolicy.findA11yWindowInfoById(windowId) == null) {
return null;
}
IBinder token = mGlobalWindowTokens.get(windowId);
@@ -3010,7 +3013,7 @@
if (!permissionGranted) {
return null;
}
- AccessibilityWindowInfo window = mSecurityPolicy.findWindowById(windowId);
+ AccessibilityWindowInfo window = mSecurityPolicy.findA11yWindowInfoById(windowId);
if (window != null) {
AccessibilityWindowInfo windowClone = AccessibilityWindowInfo.obtain(window);
windowClone.setConnectionId(mId);
@@ -3332,31 +3335,30 @@
throws RemoteException {
final int resolvedWindowId;
IAccessibilityInteractionConnection connection = null;
+ IBinder activityToken = null;
synchronized (mLock) {
if (!isCalledForCurrentUserLocked()) {
return false;
}
resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
- final boolean permissionGranted = mSecurityPolicy.canGetAccessibilityNodeInfoLocked(
- this, resolvedWindowId);
- if (!permissionGranted) {
+ if (!mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId)) {
return false;
- } else {
- connection = getConnectionLocked(resolvedWindowId);
- if (connection == null) {
- return false;
- }
- AccessibilityWindowInfo windowInfo =
- mSecurityPolicy.findWindowById(resolvedWindowId);
- if ((windowInfo != null) && windowInfo.inPictureInPicture()) {
- boolean isA11yFocusAction =
- (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS)
- || (action ==
- AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
- if ((mPictureInPictureActionReplacingConnection != null)
- && !isA11yFocusAction) {
- connection = mPictureInPictureActionReplacingConnection.mConnection;
- }
+ }
+ connection = getConnectionLocked(resolvedWindowId);
+ if (connection == null) return false;
+ final boolean isA11yFocusAction = (action == ACTION_ACCESSIBILITY_FOCUS)
+ || (action == ACTION_CLEAR_ACCESSIBILITY_FOCUS);
+ final AccessibilityWindowInfo a11yWindowInfo =
+ mSecurityPolicy.findA11yWindowInfoById(resolvedWindowId);
+ if (!isA11yFocusAction) {
+ final WindowInfo windowInfo =
+ mSecurityPolicy.findWindowInfoById(resolvedWindowId);
+ if (windowInfo != null) activityToken = windowInfo.activityToken;
+ }
+ if ((a11yWindowInfo != null) && a11yWindowInfo.inPictureInPicture()) {
+ if ((mPictureInPictureActionReplacingConnection != null)
+ && !isA11yFocusAction) {
+ connection = mPictureInPictureActionReplacingConnection.mConnection;
}
}
}
@@ -3368,6 +3370,10 @@
mPowerManager.userActivity(SystemClock.uptimeMillis(),
PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY, 0);
+ if (activityToken != null) {
+ LocalServices.getService(ActivityManagerInternal.class)
+ .setFocusedActivity(activityToken);
+ }
connection.performAccessibilityAction(accessibilityNodeId, action, arguments,
interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
@@ -4072,7 +4078,8 @@
IAccessibilityInteractionConnectionCallback originalCallback,
int resolvedWindowId, int interactionId, int interrogatingPid,
long interrogatingTid) {
- AccessibilityWindowInfo windowInfo = mSecurityPolicy.findWindowById(resolvedWindowId);
+ AccessibilityWindowInfo windowInfo =
+ mSecurityPolicy.findA11yWindowInfoById(resolvedWindowId);
if ((windowInfo == null) || !windowInfo.inPictureInPicture()
|| (mPictureInPictureActionReplacingConnection == null)) {
return originalCallback;
@@ -4193,24 +4200,12 @@
@Override
public void onWindowsForAccessibilityChanged(List<WindowInfo> windows) {
synchronized (mLock) {
- // Populate the windows to report.
- List<AccessibilityWindowInfo> reportedWindows = new ArrayList<>();
- final int receivedWindowCount = windows.size();
- for (int i = 0; i < receivedWindowCount; i++) {
- WindowInfo receivedWindow = windows.get(i);
- AccessibilityWindowInfo reportedWindow = populateReportedWindow(
- receivedWindow);
- if (reportedWindow != null) {
- reportedWindows.add(reportedWindow);
- }
- }
-
if (DEBUG) {
- Slog.i(LOG_TAG, "Windows changed: " + reportedWindows);
+ Slog.i(LOG_TAG, "Windows changed: " + windows);
}
// Let the policy update the focused and active windows.
- mSecurityPolicy.updateWindowsLocked(reportedWindows);
+ mSecurityPolicy.updateWindowsLocked(windows);
// Someone may be waiting for the windows - advertise it.
mLock.notifyAll();
@@ -4432,7 +4427,8 @@
// In Z order
public List<AccessibilityWindowInfo> mWindows;
- public SparseArray<AccessibilityWindowInfo> mWindowsById = new SparseArray<>();
+ public SparseArray<AccessibilityWindowInfo> mA11yWindowInfoById = new SparseArray<>();
+ public SparseArray<WindowInfo> mWindowInfoById = new SparseArray<>();
public int mActiveWindowId = INVALID_WINDOW_ID;
public int mFocusedWindowId = INVALID_WINDOW_ID;
@@ -4476,14 +4472,14 @@
}
public void clearWindowsLocked() {
- List<AccessibilityWindowInfo> windows = Collections.emptyList();
+ List<WindowInfo> windows = Collections.emptyList();
final int activeWindowId = mActiveWindowId;
updateWindowsLocked(windows);
mActiveWindowId = activeWindowId;
mWindows = null;
}
- public void updateWindowsLocked(List<AccessibilityWindowInfo> windows) {
+ public void updateWindowsLocked(List<WindowInfo> windows) {
if (mWindows == null) {
mWindows = new ArrayList<>();
}
@@ -4492,7 +4488,12 @@
for (int i = oldWindowCount - 1; i >= 0; i--) {
mWindows.remove(i).recycle();
}
- mWindowsById.clear();
+ mA11yWindowInfoById.clear();
+
+ for (int i = 0; i < mWindowInfoById.size(); i++) {
+ mWindowInfoById.valueAt(i).recycle();
+ }
+ mWindowInfoById.clear();
mFocusedWindowId = INVALID_WINDOW_ID;
if (!mTouchInteractionInProgress) {
@@ -4509,19 +4510,25 @@
final int windowCount = windows.size();
if (windowCount > 0) {
for (int i = 0; i < windowCount; i++) {
- AccessibilityWindowInfo window = windows.get(i);
- final int windowId = window.getId();
- if (window.isFocused()) {
- mFocusedWindowId = windowId;
- if (!mTouchInteractionInProgress) {
- mActiveWindowId = windowId;
- window.setActive(true);
- } else if (windowId == mActiveWindowId) {
- activeWindowGone = false;
+ WindowInfo windowInfo = windows.get(i);
+ AccessibilityWindowInfo window = (mWindowsForAccessibilityCallback != null)
+ ? mWindowsForAccessibilityCallback.populateReportedWindow(windowInfo)
+ : null;
+ if (window != null) {
+ final int windowId = window.getId();
+ if (window.isFocused()) {
+ mFocusedWindowId = windowId;
+ if (!mTouchInteractionInProgress) {
+ mActiveWindowId = windowId;
+ window.setActive(true);
+ } else if (windowId == mActiveWindowId) {
+ activeWindowGone = false;
+ }
}
+ mWindows.add(window);
+ mA11yWindowInfoById.put(windowId, window);
+ mWindowInfoById.put(windowId, WindowInfo.obtain(windowInfo));
}
- mWindows.add(window);
- mWindowsById.put(windowId, window);
}
if (mTouchInteractionInProgress && activeWindowGone) {
@@ -4530,7 +4537,8 @@
// Focused window may change the active one, so set the
// active window once we decided which it is.
- for (int i = 0; i < windowCount; i++) {
+ final int accessibilityWindowCount = mWindows.size();
+ for (int i = 0; i < accessibilityWindowCount; i++) {
AccessibilityWindowInfo window = mWindows.get(i);
if (window.getId() == mActiveWindowId) {
window.setActive(true);
@@ -4833,11 +4841,15 @@
if (windowId == mActiveWindowId) {
return true;
}
- return findWindowById(windowId) != null;
+ return findA11yWindowInfoById(windowId) != null;
}
- private AccessibilityWindowInfo findWindowById(int windowId) {
- return mWindowsById.get(windowId);
+ private AccessibilityWindowInfo findA11yWindowInfoById(int windowId) {
+ return mA11yWindowInfoById.get(windowId);
+ }
+
+ private WindowInfo findWindowInfoById(int windowId) {
+ return mWindowInfoById.get(windowId);
}
private AccessibilityWindowInfo getPictureInPictureWindow() {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 45387bd..d9f3454 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -24101,6 +24101,21 @@
mLastANRState = null;
}
}
+
+ @Override
+ public void setFocusedActivity(IBinder token) {
+ synchronized (ActivityManagerService.this) {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r == null) {
+ throw new IllegalArgumentException(
+ "setFocusedActivity: No activity record matching token=" + token);
+ }
+ if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
+ r, "setFocusedActivity")) {
+ mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ }
+ }
+ }
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index da739ac..02edd93 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3972,6 +3972,9 @@
windowInfo.type = mAttrs.type;
windowInfo.layer = mLayer;
windowInfo.token = mClient.asBinder();
+ if (mAppToken != null) {
+ windowInfo.activityToken = mAppToken.appToken.asBinder();
+ }
windowInfo.title = mAttrs.accessibilityTitle;
windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor;
windowInfo.focused = isFocused();