summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java81
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl3
-rw-r--r--core/java/android/view/accessibility/AccessibilityInteractionClient.java113
-rw-r--r--core/java/android/view/accessibility/AccessibilityManager.java30
4 files changed, 187 insertions, 40 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index d5368213be08..483defab43c9 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -886,7 +886,7 @@ public abstract class AccessibilityService extends Service {
* them, otherwise an empty list.
*/
public List<AccessibilityWindowInfo> getWindows() {
- return AccessibilityInteractionClient.getInstance().getWindows(mConnectionId);
+ return AccessibilityInteractionClient.getInstance(this).getWindows(mConnectionId);
}
/**
@@ -914,7 +914,8 @@ public abstract class AccessibilityService extends Service {
*/
@NonNull
public final SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
- return AccessibilityInteractionClient.getInstance().getWindowsOnAllDisplays(mConnectionId);
+ return AccessibilityInteractionClient.getInstance(this).getWindowsOnAllDisplays(
+ mConnectionId);
}
/**
@@ -940,7 +941,8 @@ public abstract class AccessibilityService extends Service {
* @return The root node if this service can retrieve window content.
*/
public AccessibilityNodeInfo getRootInActiveWindow() {
- return AccessibilityInteractionClient.getInstance().getRootInActiveWindow(mConnectionId);
+ return AccessibilityInteractionClient.getInstance(this).getRootInActiveWindow(
+ mConnectionId);
}
/**
@@ -949,7 +951,7 @@ public abstract class AccessibilityService extends Service {
*/
public final void disableSelf() {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (connection != null) {
try {
connection.disableSelf();
@@ -970,7 +972,7 @@ public abstract class AccessibilityService extends Service {
private void setDefaultTokenInternal(Context context, int displayId) {
final WindowManagerImpl wm = (WindowManagerImpl) context.getSystemService(WINDOW_SERVICE);
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
IBinder token = null;
if (connection != null) {
synchronized (mLock) {
@@ -1042,7 +1044,7 @@ public abstract class AccessibilityService extends Service {
public final @NonNull FingerprintGestureController getFingerprintGestureController() {
if (mFingerprintGestureController == null) {
mFingerprintGestureController = new FingerprintGestureController(
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId));
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId));
}
return mFingerprintGestureController;
}
@@ -1074,8 +1076,7 @@ public abstract class AccessibilityService extends Service {
@Nullable GestureResultCallback callback,
@Nullable Handler handler) {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
- mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (connection == null) {
return false;
}
@@ -1287,7 +1288,7 @@ public abstract class AccessibilityService extends Service {
private void setMagnificationCallbackEnabled(boolean enabled) {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1348,7 +1349,7 @@ public abstract class AccessibilityService extends Service {
*/
public float getScale() {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1377,7 +1378,7 @@ public abstract class AccessibilityService extends Service {
*/
public float getCenterX() {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1406,7 +1407,7 @@ public abstract class AccessibilityService extends Service {
*/
public float getCenterY() {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1440,7 +1441,7 @@ public abstract class AccessibilityService extends Service {
@NonNull
public Region getMagnificationRegion() {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1469,7 +1470,7 @@ public abstract class AccessibilityService extends Service {
*/
public boolean reset(boolean animate) {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1497,7 +1498,7 @@ public abstract class AccessibilityService extends Service {
*/
public boolean setScale(float scale, boolean animate) {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1529,7 +1530,7 @@ public abstract class AccessibilityService extends Service {
*/
public boolean setCenter(float centerX, float centerY, boolean animate) {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1701,7 +1702,7 @@ public abstract class AccessibilityService extends Service {
private void setSoftKeyboardCallbackEnabled(boolean enabled) {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1760,7 +1761,7 @@ public abstract class AccessibilityService extends Service {
@SoftKeyboardShowMode
public int getShowMode() {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1789,7 +1790,7 @@ public abstract class AccessibilityService extends Service {
*/
public boolean setShowMode(@SoftKeyboardShowMode int showMode) {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1835,7 +1836,7 @@ public abstract class AccessibilityService extends Service {
*/
public boolean switchToInputMethod(@NonNull String imeId) {
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
+ AccessibilityInteractionClient.getInstance(mService).getConnection(
mService.mConnectionId);
if (connection != null) {
try {
@@ -1888,7 +1889,7 @@ public abstract class AccessibilityService extends Service {
displayId);
if (controller == null) {
controller = new AccessibilityButtonController(
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId));
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId));
mAccessibilityButtonControllers.put(displayId, controller);
}
return controller;
@@ -1922,7 +1923,7 @@ public abstract class AccessibilityService extends Service {
*/
public final @NonNull List<AccessibilityAction> getSystemActions() {
IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (connection != null) {
try {
return connection.getSystemActions();
@@ -1955,7 +1956,7 @@ public abstract class AccessibilityService extends Service {
*/
public final boolean performGlobalAction(int action) {
IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (connection != null) {
try {
return connection.performGlobalAction(action);
@@ -1996,7 +1997,7 @@ public abstract class AccessibilityService extends Service {
* @see AccessibilityNodeInfo#FOCUS_ACCESSIBILITY
*/
public AccessibilityNodeInfo findFocus(int focus) {
- return AccessibilityInteractionClient.getInstance().findFocus(mConnectionId,
+ return AccessibilityInteractionClient.getInstance(this).findFocus(mConnectionId,
AccessibilityWindowInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, focus);
}
@@ -2012,7 +2013,7 @@ public abstract class AccessibilityService extends Service {
*/
public final AccessibilityServiceInfo getServiceInfo() {
IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (connection != null) {
try {
return connection.getServiceInfo();
@@ -2044,12 +2045,12 @@ public abstract class AccessibilityService extends Service {
*/
private void sendServiceInfo() {
IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (mInfo != null && connection != null) {
try {
connection.setServiceInfo(mInfo);
mInfo = null;
- AccessibilityInteractionClient.getInstance().clearCache();
+ AccessibilityInteractionClient.getInstance(this).clearCache();
} catch (RemoteException re) {
Log.w(LOG_TAG, "Error while setting AccessibilityServiceInfo", re);
re.rethrowFromSystemServer();
@@ -2096,8 +2097,7 @@ public abstract class AccessibilityService extends Service {
Preconditions.checkNotNull(executor, "executor cannot be null");
Preconditions.checkNotNull(callback, "callback cannot be null");
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(
- mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (connection == null) {
sendScreenshotFailure(ERROR_TAKE_SCREENSHOT_INTERNAL_ERROR, executor, callback);
return;
@@ -2136,7 +2136,7 @@ public abstract class AccessibilityService extends Service {
*/
public void setAccessibilityFocusAppearance(int strokeWidth, @ColorInt int color) {
IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (connection != null) {
try {
connection.setFocusAppearance(strokeWidth, color);
@@ -2261,12 +2261,14 @@ public abstract class AccessibilityService extends Service {
private final HandlerCaller mCaller;
private final Callbacks mCallback;
+ private final Context mContext;
private int mConnectionId = AccessibilityInteractionClient.NO_ID;
public IAccessibilityServiceClientWrapper(Context context, Looper looper,
Callbacks callback) {
mCallback = callback;
+ mContext = context;
mCaller = new HandlerCaller(context, looper, this, true /*asyncHandler*/);
}
@@ -2366,7 +2368,8 @@ public abstract class AccessibilityService extends Service {
boolean serviceWantsEvent = message.arg1 != 0;
if (event != null) {
// Send the event to AccessibilityCache via AccessibilityInteractionClient
- AccessibilityInteractionClient.getInstance().onAccessibilityEvent(event);
+ AccessibilityInteractionClient.getInstance(mContext).onAccessibilityEvent(
+ event);
if (serviceWantsEvent
&& (mConnectionId != AccessibilityInteractionClient.NO_ID)) {
// Send the event to AccessibilityService
@@ -2395,15 +2398,15 @@ public abstract class AccessibilityService extends Service {
IBinder windowToken = (IBinder) args.arg2;
args.recycle();
if (connection != null) {
- AccessibilityInteractionClient.getInstance().addConnection(mConnectionId,
- connection);
+ AccessibilityInteractionClient.getInstance(mContext).addConnection(
+ mConnectionId, connection);
mCallback.init(mConnectionId, windowToken);
mCallback.onServiceConnected();
} else {
- AccessibilityInteractionClient.getInstance().removeConnection(
+ AccessibilityInteractionClient.getInstance(mContext).removeConnection(
mConnectionId);
mConnectionId = AccessibilityInteractionClient.NO_ID;
- AccessibilityInteractionClient.getInstance().clearCache();
+ AccessibilityInteractionClient.getInstance(mContext).clearCache();
mCallback.init(AccessibilityInteractionClient.NO_ID, null);
}
return;
@@ -2415,14 +2418,14 @@ public abstract class AccessibilityService extends Service {
return;
}
case DO_CLEAR_ACCESSIBILITY_CACHE: {
- AccessibilityInteractionClient.getInstance().clearCache();
+ AccessibilityInteractionClient.getInstance(mContext).clearCache();
return;
}
case DO_ON_KEY_EVENT: {
KeyEvent event = (KeyEvent) message.obj;
try {
IAccessibilityServiceConnection connection = AccessibilityInteractionClient
- .getInstance().getConnection(mConnectionId);
+ .getInstance(mContext).getConnection(mConnectionId);
if (connection != null) {
final boolean result = mCallback.onKeyEvent(event);
final int sequence = message.arg1;
@@ -2637,7 +2640,7 @@ public abstract class AccessibilityService extends Service {
public void setGestureDetectionPassthroughRegion(int displayId, @NonNull Region region) {
Preconditions.checkNotNull(region, "region cannot be null");
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (connection != null) {
try {
connection.setGestureDetectionPassthroughRegion(displayId, region);
@@ -2663,7 +2666,7 @@ public abstract class AccessibilityService extends Service {
public void setTouchExplorationPassthroughRegion(int displayId, @NonNull Region region) {
Preconditions.checkNotNull(region, "region cannot be null");
final IAccessibilityServiceConnection connection =
- AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
if (connection != null) {
try {
connection.setTouchExplorationPassthroughRegion(displayId, region);
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index ab21dc9f14ad..923b6f41414a 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -117,4 +117,7 @@ interface IAccessibilityServiceConnection {
void setTouchExplorationPassthroughRegion(int displayId, in Region region);
void setFocusAppearance(int strokeWidth, int color);
+
+ oneway void logTrace(long timestamp, String where, String callingParams, int processId,
+ long threadId, int callingUid, in Bundle serializedCallingStackInBundle);
}
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index f63749be6df2..e64157734fdb 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -20,6 +20,7 @@ import android.accessibilityservice.IAccessibilityServiceConnection;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -39,6 +40,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
@@ -83,6 +85,8 @@ public final class AccessibilityInteractionClient
public static final int NO_ID = -1;
+ public static final String CALL_STACK = "call_stack";
+
private static final String LOG_TAG = "AccessibilityInteractionClient";
private static final boolean DEBUG = false;
@@ -113,7 +117,10 @@ public final class AccessibilityInteractionClient
private final Object mInstanceLock = new Object();
+ private final AccessibilityManager mAccessibilityManager;
+
private volatile int mInteractionId = -1;
+ private volatile int mCallingUid = Process.INVALID_UID;
private AccessibilityNodeInfo mFindAccessibilityNodeInfoResult;
@@ -152,6 +159,37 @@ public final class AccessibilityInteractionClient
}
/**
+ * @return The client for the current thread.
+ */
+ public static AccessibilityInteractionClient getInstance(Context context) {
+ final long threadId = Thread.currentThread().getId();
+ if (context != null) {
+ return getInstanceForThread(threadId, context);
+ }
+ return getInstanceForThread(threadId);
+ }
+
+ /**
+ * <strong>Note:</strong> We keep one instance per interrogating thread since
+ * the instance contains state which can lead to undesired thread interleavings.
+ * We do not have a thread local variable since other threads should be able to
+ * look up the correct client knowing a thread id. See ViewRootImpl for details.
+ *
+ * @return The client for a given <code>threadId</code>.
+ */
+ public static AccessibilityInteractionClient getInstanceForThread(
+ long threadId, Context context) {
+ synchronized (sStaticLock) {
+ AccessibilityInteractionClient client = sClients.get(threadId);
+ if (client == null) {
+ client = new AccessibilityInteractionClient(context);
+ sClients.put(threadId, client);
+ }
+ return client;
+ }
+ }
+
+ /**
* Gets a cached accessibility service connection.
*
* @param connectionId The connection id.
@@ -197,6 +235,11 @@ public final class AccessibilityInteractionClient
private AccessibilityInteractionClient() {
/* reducing constructor visibility */
+ mAccessibilityManager = null;
+ }
+
+ private AccessibilityInteractionClient(Context context) {
+ mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
}
/**
@@ -453,6 +496,15 @@ public final class AccessibilityInteractionClient
if (packageNames != null) {
List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
interactionId);
+ if (mAccessibilityManager != null
+ && mAccessibilityManager.isAccessibilityTracingEnabled()) {
+ logTrace(connection, "findAccessibilityNodeInfoByAccessibilityId",
+ "InteractionId:" + interactionId + ";Result: " + infos
+ + ";connectionId=" + connectionId + ";accessibilityWindowId="
+ + accessibilityWindowId + ";accessibilityNodeId="
+ + accessibilityNodeId + ";bypassCache=" + bypassCache
+ + ";prefetchFlags=" + prefetchFlags + ";arguments=" + arguments);
+ }
finalizeAndCacheAccessibilityNodeInfos(infos, connectionId,
bypassCache, packageNames);
if (infos != null && !infos.isEmpty()) {
@@ -514,6 +566,14 @@ public final class AccessibilityInteractionClient
if (packageNames != null) {
List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
interactionId);
+ if (mAccessibilityManager != null
+ && mAccessibilityManager.isAccessibilityTracingEnabled()) {
+ logTrace(connection, "findAccessibilityNodeInfosByViewId", "InteractionId="
+ + interactionId + ":Result: " + infos + ";connectionId="
+ + connectionId + ";accessibilityWindowId=" + accessibilityWindowId
+ + ";accessibilityNodeId=" + accessibilityNodeId + ";viewId="
+ + viewId);
+ }
if (infos != null) {
finalizeAndCacheAccessibilityNodeInfos(infos, connectionId,
false, packageNames);
@@ -568,6 +628,13 @@ public final class AccessibilityInteractionClient
if (packageNames != null) {
List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
interactionId);
+ if (mAccessibilityManager != null
+ && mAccessibilityManager.isAccessibilityTracingEnabled()) {
+ logTrace(connection, "findAccessibilityNodeInfosByText", "InteractionId="
+ + interactionId + ":Result: " + infos + ";connectionId="
+ + connectionId + ";accessibilityWindowId=" + accessibilityWindowId
+ + ";accessibilityNodeId=" + accessibilityNodeId + ";text=" + text);
+ }
if (infos != null) {
finalizeAndCacheAccessibilityNodeInfos(infos, connectionId,
false, packageNames);
@@ -621,6 +688,14 @@ public final class AccessibilityInteractionClient
if (packageNames != null) {
AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
interactionId);
+ if (mAccessibilityManager != null
+ && mAccessibilityManager.isAccessibilityTracingEnabled()) {
+ logTrace(connection, "findFocus", "InteractionId=" + interactionId
+ + ":Result: " + info + ";connectionId=" + connectionId
+ + ";accessibilityWindowId=" + accessibilityWindowId
+ + ";accessibilityNodeId=" + accessibilityNodeId + ";focusType="
+ + focusType);
+ }
finalizeAndCacheAccessibilityNodeInfo(info, connectionId, false, packageNames);
return info;
}
@@ -671,6 +746,14 @@ public final class AccessibilityInteractionClient
AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
interactionId);
finalizeAndCacheAccessibilityNodeInfo(info, connectionId, false, packageNames);
+ if (mAccessibilityManager != null
+ && mAccessibilityManager.isAccessibilityTracingEnabled()) {
+ logTrace(connection, "focusSearch", "InteractionId=" + interactionId
+ + ":Result: " + info + ";connectionId=" + connectionId
+ + ";accessibilityWindowId=" + accessibilityWindowId
+ + ";accessibilityNodeId=" + accessibilityNodeId + ";direction="
+ + direction);
+ }
return info;
}
} else {
@@ -716,7 +799,17 @@ public final class AccessibilityInteractionClient
}
if (success) {
- return getPerformAccessibilityActionResultAndClear(interactionId);
+ final boolean result =
+ getPerformAccessibilityActionResultAndClear(interactionId);
+ if (mAccessibilityManager != null
+ && mAccessibilityManager.isAccessibilityTracingEnabled()) {
+ logTrace(connection, "performAccessibilityAction", "InteractionId="
+ + interactionId + ":Result: " + result + ";connectionId="
+ + connectionId + ";accessibilityWindowId=" + accessibilityWindowId
+ + ";accessibilityNodeId=" + accessibilityNodeId + ";action="
+ + action + ";arguments=" + arguments);
+ }
+ return result;
}
} else {
if (DEBUG) {
@@ -774,6 +867,7 @@ public final class AccessibilityInteractionClient
if (interactionId > mInteractionId) {
mFindAccessibilityNodeInfoResult = info;
mInteractionId = interactionId;
+ mCallingUid = Binder.getCallingUid();
}
mInstanceLock.notifyAll();
}
@@ -823,6 +917,7 @@ public final class AccessibilityInteractionClient
mFindAccessibilityNodeInfosResult = Collections.emptyList();
}
mInteractionId = interactionId;
+ mCallingUid = Binder.getCallingUid();
}
mInstanceLock.notifyAll();
}
@@ -851,6 +946,7 @@ public final class AccessibilityInteractionClient
if (interactionId > mInteractionId) {
mPerformAccessibilityActionResult = succeeded;
mInteractionId = interactionId;
+ mCallingUid = Binder.getCallingUid();
}
mInstanceLock.notifyAll();
}
@@ -1059,4 +1155,19 @@ public final class AccessibilityInteractionClient
}
return true;
}
+
+ private void logTrace(
+ IAccessibilityServiceConnection connection, String method, String params) {
+ try {
+ Bundle b = new Bundle();
+ ArrayList<StackTraceElement> callStack = new ArrayList<StackTraceElement>(
+ Arrays.asList(Thread.currentThread().getStackTrace()));
+ b.putSerializable(CALL_STACK, callStack);
+ connection.logTrace(SystemClock.elapsedRealtimeNanos(),
+ LOG_TAG + ".callback for " + method, params, Process.myPid(),
+ Thread.currentThread().getId(), mCallingUid, b);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Failed to log trace. " + e);
+ }
+ }
}
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 56dcd5951e5e..fc9e5e2ef04e 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -111,6 +111,9 @@ public final class AccessibilityManager {
public static final int STATE_FLAG_REQUEST_MULTI_FINGER_GESTURES = 0x00000010;
/** @hide */
+ public static final int STATE_FLAG_ACCESSIBILITY_TRACING_ENABLED = 0x00000020;
+
+ /** @hide */
public static final int DALTONIZER_DISABLED = -1;
/** @hide */
@@ -232,6 +235,9 @@ public final class AccessibilityManager {
@UnsupportedAppUsage(trackingBug = 123768939L)
boolean mIsHighTextContrastEnabled;
+ // Whether accessibility tracing is enabled or not
+ boolean mIsAccessibilityTracingEnabled = false;
+
AccessibilityPolicy mAccessibilityPolicy;
private int mPerformingAction = 0;
@@ -1004,6 +1010,17 @@ public final class AccessibilityManager {
}
/**
+ * Gets accessibility tracing enabled state.
+ *
+ * @hide
+ */
+ public boolean isAccessibilityTracingEnabled() {
+ synchronized (mLock) {
+ return mIsAccessibilityTracingEnabled;
+ }
+ }
+
+ /**
* Get the preparers that are registered for an accessibility ID
*
* @param id The ID of interest
@@ -1197,6 +1214,8 @@ public final class AccessibilityManager {
(stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0;
final boolean highTextContrastEnabled =
(stateFlags & STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED) != 0;
+ final boolean accessibilityTracingEnabled =
+ (stateFlags & STATE_FLAG_ACCESSIBILITY_TRACING_ENABLED) != 0;
final boolean wasEnabled = isEnabled();
final boolean wasTouchExplorationEnabled = mIsTouchExplorationEnabled;
@@ -1218,6 +1237,8 @@ public final class AccessibilityManager {
if (wasHighTextContrastEnabled != highTextContrastEnabled) {
notifyHighTextContrastStateChanged();
}
+
+ updateAccessibilityTracingState(accessibilityTracingEnabled);
}
/**
@@ -1675,6 +1696,15 @@ public final class AccessibilityManager {
}
/**
+ * Update mIsAccessibilityTracingEnabled.
+ */
+ private void updateAccessibilityTracingState(boolean enabled) {
+ synchronized (mLock) {
+ mIsAccessibilityTracingEnabled = enabled;
+ }
+ }
+
+ /**
* Update interactive and non-interactive UI timeout.
*
* @param uiTimeout A pair of {@code int}s. First integer for interactive one, and second