From cac1d6c3c75981cea7201740fa4257fa55018444 Mon Sep 17 00:00:00 2001 From: Hongming Jin Date: Thu, 28 Jan 2021 17:08:04 -0800 Subject: Add AccessibilityTracing and trace AccessibilityController. The tracing is for a11y engineering team use for debugging purpose. It is disabled by default and can be enabled only by shell command. The cl for the shell command change will be submitted after this cl. See "Test" section below for the command details. Expose interface through WindowManagerInternal to allow a11y use the trace feature. Bug: 157601519 Test: adb shell cmd accessibility start-trace adb shell cmd accessibility stop-trace Change-Id: I4cdb8798b29cd4a246db71d8cb17fe2c4429cd51 --- .../android/server/wm/AccessibilityController.java | 712 +++++++++++++++++---- .../android/server/wm/AppTransitionController.java | 3 +- .../java/com/android/server/wm/DisplayContent.java | 8 +- .../server/wm/DockedStackDividerController.java | 2 +- .../core/java/com/android/server/wm/ShellRoot.java | 2 +- .../java/com/android/server/wm/WindowAnimator.java | 2 +- .../android/server/wm/WindowManagerInternal.java | 40 ++ .../android/server/wm/WindowManagerService.java | 43 +- .../java/com/android/server/wm/WindowState.java | 12 +- .../com/android/server/wm/WindowStateAnimator.java | 2 +- 10 files changed, 677 insertions(+), 149 deletions(-) diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 2ecefeafcf5c..3bbc81a696e6 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -16,12 +16,27 @@ package com.android.server.wm; +import static android.os.Build.IS_USER; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; +import static com.android.server.accessibility.AccessibilityTraceFileProto.ENTRY; +import static com.android.server.accessibility.AccessibilityTraceFileProto.MAGIC_NUMBER; +import static com.android.server.accessibility.AccessibilityTraceFileProto.MAGIC_NUMBER_H; +import static com.android.server.accessibility.AccessibilityTraceFileProto.MAGIC_NUMBER_L; +import static com.android.server.accessibility.AccessibilityTraceProto.ACCESSIBILITY_SERVICE; +import static com.android.server.accessibility.AccessibilityTraceProto.CALENDAR_TIME; +import static com.android.server.accessibility.AccessibilityTraceProto.CALLING_PARAMS; +import static com.android.server.accessibility.AccessibilityTraceProto.CALLING_PKG; +import static com.android.server.accessibility.AccessibilityTraceProto.CALLING_STACKS; +import static com.android.server.accessibility.AccessibilityTraceProto.ELAPSED_REALTIME_NANOS; +import static com.android.server.accessibility.AccessibilityTraceProto.PROCESS_NAME; +import static com.android.server.accessibility.AccessibilityTraceProto.THREAD_ID_NAME; +import static com.android.server.accessibility.AccessibilityTraceProto.WHERE; +import static com.android.server.accessibility.AccessibilityTraceProto.WINDOW_MANAGER_SERVICE; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.utils.RegionUtils.forEachRect; @@ -29,7 +44,9 @@ import static com.android.server.wm.utils.RegionUtils.forEachRect; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.NonNull; +import android.app.Application; import android.content.Context; +import android.content.pm.PackageManagerInternal; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; @@ -41,15 +58,20 @@ import android.graphics.PorterDuff.Mode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; +import android.os.Binder; import android.os.Handler; +import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Process; +import android.os.SystemClock; import android.util.ArraySet; import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; import android.util.TypedValue; +import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.InsetsSource; import android.view.MagnificationSpec; @@ -64,13 +86,22 @@ import android.view.animation.Interpolator; import com.android.internal.R; import com.android.internal.os.SomeArgs; +import com.android.internal.util.TraceBuffer; +import com.android.server.LocalServices; import com.android.server.policy.WindowManagerPolicy; +import com.android.server.wm.WindowManagerInternal.AccessibilityControllerInternal; import com.android.server.wm.WindowManagerInternal.MagnificationCallbacks; import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback; +import java.io.File; +import java.io.IOException; import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -79,26 +110,37 @@ import java.util.Set; * This class contains the accessibility related logic of the window manager. */ final class AccessibilityController { + private static final String TAG = AccessibilityController.class.getSimpleName(); - private final WindowManagerService mService; + private static final Object STATIC_LOCK = new Object(); + static AccessibilityControllerInternal + getAccessibilityControllerInternal(WindowManagerService service) { + return AccessibilityControllerInternalImpl.getInstance(service); + } + private final AccessibilityTracing mAccessibilityTracing; + private final WindowManagerService mService; private static final Rect EMPTY_RECT = new Rect(); private static final float[] sTempFloats = new float[9]; - public AccessibilityController(WindowManagerService service) { + AccessibilityController(WindowManagerService service) { mService = service; + mAccessibilityTracing = AccessibilityTracing.getInstance(service); } private SparseArray mDisplayMagnifiers = new SparseArray<>(); - private SparseArray mWindowsForAccessibilityObserver = new SparseArray<>(); // Set to true if initializing window population complete. private boolean mAllObserversInitialized = true; - public boolean setMagnificationCallbacksLocked(int displayId, - MagnificationCallbacks callbacks) { + boolean setMagnificationCallbacks(int displayId, MagnificationCallbacks callbacks) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + TAG + ".setMagnificationCallbacks", + "displayId=" + displayId + "; callbacks={" + callbacks + "}"); + } boolean result = false; if (callbacks != null) { if (mDisplayMagnifiers.get(displayId) != null) { @@ -118,7 +160,7 @@ final class AccessibilityController { if (displayMagnifier == null) { throw new IllegalStateException("Magnification callbacks already cleared!"); } - displayMagnifier.destroyLocked(); + displayMagnifier.destroy(); mDisplayMagnifiers.remove(displayId); result = true; } @@ -133,8 +175,13 @@ final class AccessibilityController { * @param callback The callback. * @return {@code false} if display id is not valid or an embedded display. */ - public boolean setWindowsForAccessibilityCallbackLocked(int displayId, + boolean setWindowsForAccessibilityCallback(int displayId, WindowsForAccessibilityCallback callback) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + TAG + ".setWindowsForAccessibilityCallback", + "displayId=" + displayId + "; callback={" + callback + "}"); + } final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId); if (dc == null) { return false; @@ -147,7 +194,7 @@ final class AccessibilityController { // empty, that means this mapping didn't be set, and needs to do this again. // This happened when accessibility window observer is disabled and enabled again. if (mWindowsForAccessibilityObserver.get(displayId) == null) { - handleWindowObserverOfEmbeddedDisplayLocked(displayId, dc.getParentWindow()); + handleWindowObserverOfEmbeddedDisplay(displayId, dc.getParentWindow()); } return false; } else if (mWindowsForAccessibilityObserver.get(displayId) != null) { @@ -181,7 +228,12 @@ final class AccessibilityController { return true; } - public void performComputeChangedWindowsNotLocked(int displayId, boolean forceSend) { + void performComputeChangedWindowsNot(int displayId, boolean forceSend) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + TAG + ".performComputeChangedWindowsNot", + "displayId=" + displayId + "; forceSend=" + forceSend); + } WindowsForAccessibilityObserver observer = null; synchronized (mService.mGlobalLock) { final WindowsForAccessibilityObserver windowsForA11yObserver = @@ -191,86 +243,119 @@ final class AccessibilityController { } } if (observer != null) { - observer.performComputeChangedWindowsNotLocked(forceSend); + observer.performComputeChangedWindows(forceSend); } } - public void setMagnificationSpecLocked(int displayId, MagnificationSpec spec) { + void setMagnificationSpec(int displayId, MagnificationSpec spec) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(TAG + ".setMagnificationSpec", + "displayId=" + displayId + "; spec={" + spec + "}"); + } final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.setMagnificationSpecLocked(spec); + displayMagnifier.setMagnificationSpec(spec); } final WindowsForAccessibilityObserver windowsForA11yObserver = mWindowsForAccessibilityObserver.get(displayId); if (windowsForA11yObserver != null) { - windowsForA11yObserver.scheduleComputeChangedWindowsLocked(); + windowsForA11yObserver.scheduleComputeChangedWindows(); } } - public void getMagnificationRegionLocked(int displayId, Region outMagnificationRegion) { + void getMagnificationRegion(int displayId, Region outMagnificationRegion) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(TAG + ".getMagnificationRegion", + "displayId=" + displayId + "; outMagnificationRegion={" + outMagnificationRegion + + "}"); + } final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.getMagnificationRegionLocked(outMagnificationRegion); + displayMagnifier.getMagnificationRegion(outMagnificationRegion); } } - public void onRectangleOnScreenRequestedLocked(int displayId, Rect rectangle) { + void onRectangleOnScreenRequested(int displayId, Rect rectangle) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + TAG + ".onRectangleOnScreenRequested", + "displayId=" + displayId + "; rectangle={" + rectangle + "}"); + } final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.onRectangleOnScreenRequestedLocked(rectangle); + displayMagnifier.onRectangleOnScreenRequested(rectangle); } // Not relevant for the window observer. } - public void onWindowLayersChangedLocked(int displayId) { + void onWindowLayersChanged(int displayId) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + TAG + ".onWindowLayersChanged", "displayId=" + displayId); + } final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.onWindowLayersChangedLocked(); + displayMagnifier.onWindowLayersChanged(); } final WindowsForAccessibilityObserver windowsForA11yObserver = mWindowsForAccessibilityObserver.get(displayId); if (windowsForA11yObserver != null) { - windowsForA11yObserver.scheduleComputeChangedWindowsLocked(); + windowsForA11yObserver.scheduleComputeChangedWindows(); } } - public void onRotationChangedLocked(DisplayContent displayContent) { + void onRotationChanged(DisplayContent displayContent) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(TAG + ".onRotationChanged", + "displayContent={" + displayContent + "}"); + } final int displayId = displayContent.getDisplayId(); final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.onRotationChangedLocked(displayContent); + displayMagnifier.onRotationChanged(displayContent); } final WindowsForAccessibilityObserver windowsForA11yObserver = mWindowsForAccessibilityObserver.get(displayId); if (windowsForA11yObserver != null) { - windowsForA11yObserver.scheduleComputeChangedWindowsLocked(); + windowsForA11yObserver.scheduleComputeChangedWindows(); } } - public void onAppWindowTransitionLocked(int displayId, int transition) { + void onAppWindowTransition(int displayId, int transition) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(TAG + ".onAppWindowTransition", + "displayId=" + displayId + "; transition=" + transition); + } final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.onAppWindowTransitionLocked(displayId, transition); + displayMagnifier.onAppWindowTransition(displayId, transition); } // Not relevant for the window observer. } - public void onWindowTransitionLocked(WindowState windowState, int transition) { + void onWindowTransition(WindowState windowState, int transition) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(TAG + ".onWindowTransition", + "windowState={" + windowState + "}; transition=" + transition); + } final int displayId = windowState.getDisplayId(); final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.onWindowTransitionLocked(windowState, transition); + displayMagnifier.onWindowTransition(windowState, transition); } final WindowsForAccessibilityObserver windowsForA11yObserver = mWindowsForAccessibilityObserver.get(displayId); if (windowsForA11yObserver != null) { - windowsForA11yObserver.scheduleComputeChangedWindowsLocked(); + windowsForA11yObserver.scheduleComputeChangedWindows(); } } - public void onWindowFocusChangedNotLocked(int displayId) { + void onWindowFocusChangedNot(int displayId) { // Not relevant for the display magnifier. - + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + TAG + ".onWindowFocusChangedNot", "displayId=" + displayId); + } WindowsForAccessibilityObserver observer = null; synchronized (mService.mGlobalLock) { final WindowsForAccessibilityObserver windowsForA11yObserver = @@ -280,7 +365,7 @@ final class AccessibilityController { } } if (observer != null) { - observer.performComputeChangedWindowsNotLocked(false); + observer.performComputeChangedWindows(false); } // Since we abandon initializing observers if no window has focus, make sure all observers // are initialized. @@ -311,7 +396,7 @@ final class AccessibilityController { boolean areAllObserversInitialized = true; for (int i = unInitializedObservers.size() - 1; i >= 0; --i) { final WindowsForAccessibilityObserver observer = unInitializedObservers.get(i); - observer.performComputeChangedWindowsNotLocked(true); + observer.performComputeChangedWindows(true); areAllObserversInitialized &= observer.mInitialized; } synchronized (mService.mGlobalLock) { @@ -324,50 +409,89 @@ final class AccessibilityController { * another display is also taken into consideration. * @param displayIds the display ids of displays when the situation happens. */ - public void onSomeWindowResizedOrMovedLocked(int... displayIds) { + void onSomeWindowResizedOrMoved(int... displayIds) { + onSomeWindowResizedOrMovedWithCallingUid(Binder.getCallingUid(), displayIds); + } + + void onSomeWindowResizedOrMovedWithCallingUid(int callingUid, int... displayIds) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + TAG + ".onSomeWindowResizedOrMoved", + "displayIds={" + displayIds.toString() + "}", + "".getBytes(), + callingUid); + } // Not relevant for the display magnifier. for (int i = 0; i < displayIds.length; i++) { final WindowsForAccessibilityObserver windowsForA11yObserver = mWindowsForAccessibilityObserver.get(displayIds[i]); if (windowsForA11yObserver != null) { - windowsForA11yObserver.scheduleComputeChangedWindowsLocked(); + windowsForA11yObserver.scheduleComputeChangedWindows(); } } } - public void drawMagnifiedRegionBorderIfNeededLocked(int displayId, - SurfaceControl.Transaction t) { + void drawMagnifiedRegionBorderIfNeeded(int displayId, SurfaceControl.Transaction t) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + TAG + ".drawMagnifiedRegionBorderIfNeeded", + "displayId=" + displayId + "; transaction={" + t + "}"); + } final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.drawMagnifiedRegionBorderIfNeededLocked(t); + displayMagnifier.drawMagnifiedRegionBorderIfNeeded(t); } // Not relevant for the window observer. } - public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) { + MagnificationSpec getMagnificationSpecForWindow(WindowState windowState) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(TAG + ".getMagnificationSpecForWindow", + "windowState={" + windowState + "}"); + } final int displayId = windowState.getDisplayId(); final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - return displayMagnifier.getMagnificationSpecForWindowLocked(windowState); + return displayMagnifier.getMagnificationSpecForWindow(windowState); } return null; } - public boolean hasCallbacksLocked() { + boolean hasCallbacks() { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(TAG + ".hasCallbacks"); + } return (mDisplayMagnifiers.size() > 0 || mWindowsForAccessibilityObserver.size() > 0); } - public void setForceShowMagnifiableBoundsLocked(int displayId, boolean show) { + void setForceShowMagnifiableBounds(int displayId, boolean show) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(TAG + ".setForceShowMagnifiableBounds", + "displayId=" + displayId + "; show=" + show); + } final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.setForceShowMagnifiableBoundsLocked(show); + displayMagnifier.setForceShowMagnifiableBounds(show); displayMagnifier.showMagnificationBoundsIfNeeded(); } } - public void handleWindowObserverOfEmbeddedDisplayLocked(int embeddedDisplayId, + void handleWindowObserverOfEmbeddedDisplay(int embeddedDisplayId, WindowState parentWindow) { + handleWindowObserverOfEmbeddedDisplay( + embeddedDisplayId, parentWindow, Binder.getCallingUid()); + } + + void handleWindowObserverOfEmbeddedDisplay( + int embeddedDisplayId, WindowState parentWindow, int callingUid) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(TAG + ".handleWindowObserverOfEmbeddedDisplay", + "embeddedDisplayId=" + embeddedDisplayId + "; parentWindowState={" + + parentWindow + "}", + "".getBytes(), + callingUid); + } if (embeddedDisplayId == Display.DEFAULT_DISPLAY || parentWindow == null) { return; } @@ -390,7 +514,7 @@ final class AccessibilityController { } } - private static void populateTransformationMatrixLocked(WindowState windowState, + private static void populateTransformationMatrix(WindowState windowState, Matrix outMatrix) { windowState.getTransformationMatrix(sTempFloats, outMatrix); } @@ -451,6 +575,7 @@ final class AccessibilityController { private final Handler mHandler; private final DisplayContent mDisplayContent; private final Display mDisplay; + private final AccessibilityTracing mAccessibilityTracing; private final MagnificationCallbacks mCallbacks; @@ -458,7 +583,7 @@ final class AccessibilityController { private boolean mForceShowMagnifiableBounds = false; - public DisplayMagnifier(WindowManagerService windowManagerService, + DisplayMagnifier(WindowManagerService windowManagerService, DisplayContent displayContent, Display display, MagnificationCallbacks callbacks) { @@ -469,36 +594,58 @@ final class AccessibilityController { mDisplay = display; mHandler = new MyHandler(mService.mH.getLooper()); mMagnifedViewport = new MagnifiedViewport(); + mAccessibilityTracing = AccessibilityTracing.getInstance(mService); mLongAnimationDuration = mDisplayContext.getResources().getInteger( com.android.internal.R.integer.config_longAnimTime); + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".DisplayMagnifier.constructor", + "windowManagerService={" + windowManagerService + "}; displayContent={" + + displayContent + "}; display={" + display + "}; callbacks={" + + callbacks + "}"); + } } - public void setMagnificationSpecLocked(MagnificationSpec spec) { - mMagnifedViewport.updateMagnificationSpecLocked(spec); - mMagnifedViewport.recomputeBoundsLocked(); + void setMagnificationSpec(MagnificationSpec spec) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + LOG_TAG + ".setMagnificationSpec", "spec={" + spec + "}"); + } + mMagnifedViewport.updateMagnificationSpec(spec); + mMagnifedViewport.recomputeBounds(); mService.applyMagnificationSpecLocked(mDisplay.getDisplayId(), spec); mService.scheduleAnimationLocked(); } - public void setForceShowMagnifiableBoundsLocked(boolean show) { + void setForceShowMagnifiableBounds(boolean show) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + LOG_TAG + ".setForceShowMagnifiableBounds", "show=" + show); + } mForceShowMagnifiableBounds = show; - mMagnifedViewport.setMagnifiedRegionBorderShownLocked(show, true); + mMagnifedViewport.setMagnifiedRegionBorderShown(show, true); } - public boolean isForceShowingMagnifiableBoundsLocked() { + boolean isForceShowingMagnifiableBounds() { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".isForceShowingMagnifiableBounds"); + } return mForceShowMagnifiableBounds; } - public void onRectangleOnScreenRequestedLocked(Rect rectangle) { + void onRectangleOnScreenRequested(Rect rectangle) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + LOG_TAG + ".onRectangleOnScreenRequested", "rectangle={" + rectangle + "}"); + } if (DEBUG_RECTANGLE_REQUESTED) { Slog.i(LOG_TAG, "Rectangle on screen requested: " + rectangle); } - if (!mMagnifedViewport.isMagnifyingLocked()) { + if (!mMagnifedViewport.isMagnifying()) { return; } Rect magnifiedRegionBounds = mTempRect2; - mMagnifedViewport.getMagnifiedFrameInContentCoordsLocked(magnifiedRegionBounds); + mMagnifedViewport.getMagnifiedFrameInContentCoords(magnifiedRegionBounds); if (magnifiedRegionBounds.contains(rectangle)) { return; } @@ -511,31 +658,42 @@ final class AccessibilityController { args).sendToTarget(); } - public void onWindowLayersChangedLocked() { + void onWindowLayersChanged() { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".onWindowLayersChanged"); + } if (DEBUG_LAYERS) { Slog.i(LOG_TAG, "Layers changed."); } - mMagnifedViewport.recomputeBoundsLocked(); + mMagnifedViewport.recomputeBounds(); mService.scheduleAnimationLocked(); } - public void onRotationChangedLocked(DisplayContent displayContent) { + void onRotationChanged(DisplayContent displayContent) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + LOG_TAG + ".onRotationChanged", "displayContent={" + displayContent + "}"); + } if (DEBUG_ROTATION) { final int rotation = displayContent.getRotation(); Slog.i(LOG_TAG, "Rotation: " + Surface.rotationToString(rotation) + " displayId: " + displayContent.getDisplayId()); } - mMagnifedViewport.onRotationChangedLocked(displayContent.getPendingTransaction()); + mMagnifedViewport.onRotationChanged(displayContent.getPendingTransaction()); mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_ROTATION_CHANGED); } - public void onAppWindowTransitionLocked(int displayId, int transition) { + void onAppWindowTransition(int displayId, int transition) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".onAppWindowTransition", + "displayId=" + displayId + "; transition=" + transition); + } if (DEBUG_WINDOW_TRANSITIONS) { Slog.i(LOG_TAG, "Window transition: " + AppTransition.appTransitionOldToString(transition) + " displayId: " + displayId); } - final boolean magnifying = mMagnifedViewport.isMagnifyingLocked(); + final boolean magnifying = mMagnifedViewport.isMagnifying(); if (magnifying) { switch (transition) { case WindowManager.TRANSIT_OLD_ACTIVITY_OPEN: @@ -550,13 +708,17 @@ final class AccessibilityController { } } - public void onWindowTransitionLocked(WindowState windowState, int transition) { + void onWindowTransition(WindowState windowState, int transition) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".onWindowTransition", + "windowState={" + windowState + "}; transition=" + transition); + } if (DEBUG_WINDOW_TRANSITIONS) { Slog.i(LOG_TAG, "Window transition: " + AppTransition.appTransitionOldToString(transition) + " displayId: " + windowState.getDisplayId()); } - final boolean magnifying = mMagnifedViewport.isMagnifyingLocked(); + final boolean magnifying = mMagnifedViewport.isMagnifying(); final int type = windowState.mAttrs.type; switch (transition) { case WindowManagerPolicy.TRANSIT_ENTER: @@ -586,7 +748,7 @@ final class AccessibilityController { case WindowManager.LayoutParams.TYPE_QS_DIALOG: case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL: { Rect magnifiedRegionBounds = mTempRect2; - mMagnifedViewport.getMagnifiedFrameInContentCoordsLocked( + mMagnifedViewport.getMagnifiedFrameInContentCoords( magnifiedRegionBounds); Rect touchableRegionBounds = mTempRect1; windowState.getTouchableRegion(mTempRegion1); @@ -604,8 +766,12 @@ final class AccessibilityController { } } - public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) { - MagnificationSpec spec = mMagnifedViewport.getMagnificationSpecLocked(); + MagnificationSpec getMagnificationSpecForWindow(WindowState windowState) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".getMagnificationSpecForWindow", + "windowState={" + windowState + "}"); + } + MagnificationSpec spec = mMagnifedViewport.getMagnificationSpec(); if (spec != null && !spec.isNop()) { if (!windowState.shouldMagnify()) { return null; @@ -614,24 +780,38 @@ final class AccessibilityController { return spec; } - public void getMagnificationRegionLocked(Region outMagnificationRegion) { + void getMagnificationRegion(Region outMagnificationRegion) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".getMagnificationRegion", + "outMagnificationRegion={" + outMagnificationRegion + "}"); + } // Make sure we're working with the most current bounds - mMagnifedViewport.recomputeBoundsLocked(); - mMagnifedViewport.getMagnificationRegionLocked(outMagnificationRegion); + mMagnifedViewport.recomputeBounds(); + mMagnifedViewport.getMagnificationRegion(outMagnificationRegion); } - public void destroyLocked() { + void destroy() { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".destroy"); + } mMagnifedViewport.destroyWindow(); } // Can be called outside of a surface transaction - public void showMagnificationBoundsIfNeeded() { + void showMagnificationBoundsIfNeeded() { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".showMagnificationBoundsIfNeeded"); + } mHandler.obtainMessage(MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED) .sendToTarget(); } - public void drawMagnifiedRegionBorderIfNeededLocked(SurfaceControl.Transaction t) { - mMagnifedViewport.drawWindowIfNeededLocked(t); + void drawMagnifiedRegionBorderIfNeeded(SurfaceControl.Transaction t) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".drawMagnifiedRegionBorderIfNeeded", + "transition={" + t + "}"); + } + mMagnifedViewport.drawWindowIfNeeded(t); } void dump(PrintWriter pw, String prefix) { @@ -665,7 +845,7 @@ final class AccessibilityController { private boolean mFullRedrawNeeded; private int mTempLayer = 0; - public MagnifiedViewport() { + MagnifiedViewport() { mBorderWidth = mDisplayContext.getResources().getDimension( com.android.internal.R.dimen.accessibility_magnification_indicator_width); mHalfBorderWidth = (int) Math.ceil(mBorderWidth / 2); @@ -681,14 +861,14 @@ final class AccessibilityController { mCircularPath = null; } - recomputeBoundsLocked(); + recomputeBounds(); } - public void getMagnificationRegionLocked(@NonNull Region outMagnificationRegion) { + void getMagnificationRegion(@NonNull Region outMagnificationRegion) { outMagnificationRegion.set(mMagnificationRegion); } - public void updateMagnificationSpecLocked(MagnificationSpec spec) { + void updateMagnificationSpec(MagnificationSpec spec) { if (spec != null) { mMagnificationSpec.initialize(spec.scale, spec.offsetX, spec.offsetY); } else { @@ -698,12 +878,12 @@ final class AccessibilityController { // to show the border. We will do so when the pending message is handled. if (!mHandler.hasMessages( MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED)) { - setMagnifiedRegionBorderShownLocked( - isMagnifyingLocked() || isForceShowingMagnifiableBoundsLocked(), true); + setMagnifiedRegionBorderShown( + isMagnifying() || isForceShowingMagnifiableBounds(), true); } } - public void recomputeBoundsLocked() { + void recomputeBounds() { mDisplay.getRealSize(mTempPoint); final int screenWidth = mTempPoint.x; final int screenHeight = mTempPoint.y; @@ -721,7 +901,7 @@ final class AccessibilityController { SparseArray visibleWindows = mTempWindowStates; visibleWindows.clear(); - populateWindowsOnScreenLocked(visibleWindows); + populateWindowsOnScreen(visibleWindows); final int visibleWindowCount = visibleWindows.size(); for (int i = visibleWindowCount - 1; i >= 0; i--) { @@ -736,7 +916,7 @@ final class AccessibilityController { // Consider the touchable portion of the window Matrix matrix = mTempMatrix; - populateTransformationMatrixLocked(windowState, matrix); + populateTransformationMatrix(windowState, matrix); Region touchableRegion = mTempRegion3; windowState.getTouchableRegion(touchableRegion); Rect touchableFrame = mTempRect1; @@ -848,24 +1028,24 @@ final class AccessibilityController { return letterboxBounds; } - public void onRotationChangedLocked(SurfaceControl.Transaction t) { + void onRotationChanged(SurfaceControl.Transaction t) { // If we are showing the magnification border, hide it immediately so // the user does not see strange artifacts during rotation. The screenshot // used for rotation already has the border. After the rotation is complete // we will show the border. - if (isMagnifyingLocked() || isForceShowingMagnifiableBoundsLocked()) { - setMagnifiedRegionBorderShownLocked(false, false); + if (isMagnifying() || isForceShowingMagnifiableBounds()) { + setMagnifiedRegionBorderShown(false, false); final long delay = (long) (mLongAnimationDuration * mService.getWindowAnimationScaleLocked()); Message message = mHandler.obtainMessage( MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED); mHandler.sendMessageDelayed(message, delay); } - recomputeBoundsLocked(); + recomputeBounds(); mWindow.updateSize(t); } - public void setMagnifiedRegionBorderShownLocked(boolean shown, boolean animate) { + void setMagnifiedRegionBorderShown(boolean shown, boolean animate) { if (shown) { mFullRedrawNeeded = true; mOldMagnificationRegion.set(0, 0, 0, 0); @@ -873,31 +1053,31 @@ final class AccessibilityController { mWindow.setShown(shown, animate); } - public void getMagnifiedFrameInContentCoordsLocked(Rect rect) { + void getMagnifiedFrameInContentCoords(Rect rect) { MagnificationSpec spec = mMagnificationSpec; mMagnificationRegion.getBounds(rect); rect.offset((int) -spec.offsetX, (int) -spec.offsetY); rect.scale(1.0f / spec.scale); } - public boolean isMagnifyingLocked() { + boolean isMagnifying() { return mMagnificationSpec.scale > 1.0f; } - public MagnificationSpec getMagnificationSpecLocked() { + MagnificationSpec getMagnificationSpec() { return mMagnificationSpec; } - public void drawWindowIfNeededLocked(SurfaceControl.Transaction t) { - recomputeBoundsLocked(); + void drawWindowIfNeeded(SurfaceControl.Transaction t) { + recomputeBounds(); mWindow.drawIfNeeded(t); } - public void destroyWindow() { + void destroyWindow() { mWindow.releaseSurface(); } - private void populateWindowsOnScreenLocked(SparseArray outWindows) { + private void populateWindowsOnScreen(SparseArray outWindows) { mTempLayer = 0; mDisplayContent.forAllWindows((w) -> { if (w.isOnScreen() && w.isVisible() @@ -929,7 +1109,7 @@ final class AccessibilityController { private boolean mInvalidated; - public ViewportWindow(Context context) { + ViewportWindow(Context context) { SurfaceControl surfaceControl = null; try { mDisplay.getRealSize(mTempPoint); @@ -971,7 +1151,7 @@ final class AccessibilityController { mInvalidated = true; } - public void setShown(boolean shown, boolean animate) { + void setShown(boolean shown, boolean animate) { synchronized (mService.mGlobalLock) { if (mShown == shown) { return; @@ -986,13 +1166,13 @@ final class AccessibilityController { @SuppressWarnings("unused") // Called reflectively from an animator. - public int getAlpha() { + int getAlpha() { synchronized (mService.mGlobalLock) { return mAlpha; } } - public void setAlpha(int alpha) { + void setAlpha(int alpha) { synchronized (mService.mGlobalLock) { if (mAlpha == alpha) { return; @@ -1005,7 +1185,7 @@ final class AccessibilityController { } } - public void setBounds(Region bounds) { + void setBounds(Region bounds) { synchronized (mService.mGlobalLock) { if (mBounds.equals(bounds)) { return; @@ -1018,7 +1198,7 @@ final class AccessibilityController { } } - public void updateSize(SurfaceControl.Transaction t) { + void updateSize(SurfaceControl.Transaction t) { synchronized (mService.mGlobalLock) { mDisplay.getRealSize(mTempPoint); t.setBufferSize(mSurfaceControl, mTempPoint.x, mTempPoint.y); @@ -1026,7 +1206,7 @@ final class AccessibilityController { } } - public void invalidate(Rect dirtyRect) { + void invalidate(Rect dirtyRect) { if (dirtyRect != null) { mDirtyRect.set(dirtyRect); } else { @@ -1036,7 +1216,7 @@ final class AccessibilityController { mService.scheduleAnimationLocked(); } - public void drawIfNeeded(SurfaceControl.Transaction t) { + void drawIfNeeded(SurfaceControl.Transaction t) { synchronized (mService.mGlobalLock) { if (!mInvalidated) { return; @@ -1078,7 +1258,7 @@ final class AccessibilityController { } } - public void releaseSurface() { + void releaseSurface() { mService.mTransactionFactory.get().remove(mSurfaceControl).apply(); mSurface.release(); } @@ -1101,7 +1281,7 @@ final class AccessibilityController { private final ValueAnimator mShowHideFrameAnimator; - public AnimationController(Context context, Looper looper) { + AnimationController(Context context, Looper looper) { super(looper); mShowHideFrameAnimator = ObjectAnimator.ofInt(ViewportWindow.this, PROPERTY_NAME_ALPHA, MIN_ALPHA, MAX_ALPHA); @@ -1114,7 +1294,7 @@ final class AccessibilityController { mShowHideFrameAnimator.setDuration(longAnimationDuration); } - public void onFrameShownStateChanged(boolean shown, boolean animate) { + void onFrameShownStateChanged(boolean shown, boolean animate) { obtainMessage(MSG_FRAME_SHOWN_STATE_CHANGED, shown ? 1 : 0, animate ? 1 : 0).sendToTarget(); } @@ -1158,7 +1338,7 @@ final class AccessibilityController { public static final int MESSAGE_NOTIFY_ROTATION_CHANGED = 4; public static final int MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED = 5; - public MyHandler(Looper looper) { + MyHandler(Looper looper) { super(looper); } @@ -1193,9 +1373,9 @@ final class AccessibilityController { case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : { synchronized (mService.mGlobalLock) { - if (mMagnifedViewport.isMagnifyingLocked() - || isForceShowingMagnifiableBoundsLocked()) { - mMagnifedViewport.setMagnifiedRegionBorderShownLocked(true, true); + if (mMagnifedViewport.isMagnifying() + || isForceShowingMagnifiableBounds()) { + mMagnifedViewport.setMagnifiedRegionBorderShown(true, true); mService.scheduleAnimationLocked(); } } @@ -1252,6 +1432,8 @@ final class AccessibilityController { private final Handler mHandler; + private final AccessibilityTracing mAccessibilityTracing; + private final WindowsForAccessibilityCallback mCallback; private final int mDisplayId; @@ -1263,24 +1445,32 @@ final class AccessibilityController { // Set to true if initializing window population complete. private boolean mInitialized; - public WindowsForAccessibilityObserver(WindowManagerService windowManagerService, + WindowsForAccessibilityObserver(WindowManagerService windowManagerService, int displayId, WindowsForAccessibilityCallback callback) { mService = windowManagerService; mCallback = callback; mDisplayId = displayId; mHandler = new MyHandler(mService.mH.getLooper()); + mAccessibilityTracing = AccessibilityTracing.getInstance(mService); mRecurringAccessibilityEventsIntervalMillis = ViewConfiguration .getSendRecurringAccessibilityEventsInterval(); computeChangedWindows(true); } - public void performComputeChangedWindowsNotLocked(boolean forceSend) { + void performComputeChangedWindows(boolean forceSend) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".performComputeChangedWindows", + "forceSend=" + forceSend); + } mHandler.removeMessages(MyHandler.MESSAGE_COMPUTE_CHANGED_WINDOWS); computeChangedWindows(forceSend); } - public void scheduleComputeChangedWindowsLocked() { + void scheduleComputeChangedWindows() { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState(LOG_TAG + ".scheduleComputeChangedWindows"); + } if (!mHandler.hasMessages(MyHandler.MESSAGE_COMPUTE_CHANGED_WINDOWS)) { mHandler.sendEmptyMessageDelayed(MyHandler.MESSAGE_COMPUTE_CHANGED_WINDOWS, mRecurringAccessibilityEventsIntervalMillis); @@ -1307,7 +1497,11 @@ final class AccessibilityController { * * @param forceSend Send the windows the accessibility even if they haven't changed. */ - public void computeChangedWindows(boolean forceSend) { + void computeChangedWindows(boolean forceSend) { + if (mAccessibilityTracing.isEnabled()) { + mAccessibilityTracing.logState( + LOG_TAG + ".computeChangedWindows", "forceSend=" + forceSend); + } if (DEBUG) { Slog.i(LOG_TAG, "computeChangedWindows()"); } @@ -1343,7 +1537,7 @@ final class AccessibilityController { unaccountedSpace.set(0, 0, screenWidth, screenHeight); final SparseArray visibleWindows = mTempWindowStates; - populateVisibleWindowsOnScreenLocked(visibleWindows); + populateVisibleWindowsOnScreen(visibleWindows); Set addedWindows = mTempBinderSet; addedWindows.clear(); @@ -1518,7 +1712,7 @@ final class AccessibilityController { // Map the frame to get what appears on the screen. Matrix matrix = mTempMatrix; - populateTransformationMatrixLocked(windowState, matrix); + populateTransformationMatrix(windowState, matrix); forEachRect(touchableRegion, rect -> { // Move to origin as all transforms are captured by the matrix. @@ -1563,7 +1757,7 @@ final class AccessibilityController { && windowType != WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION); } - private void populateVisibleWindowsOnScreenLocked(SparseArray outWindows) { + private void populateVisibleWindowsOnScreen(SparseArray outWindows) { final List tempWindowStatesList = new ArrayList<>(); final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId); if (dc == null) { @@ -1637,4 +1831,292 @@ final class AccessibilityController { } } } + + private static final class AccessibilityControllerInternalImpl + implements AccessibilityControllerInternal { + + private static AccessibilityControllerInternal sInstance; + static AccessibilityControllerInternal getInstance(WindowManagerService service) { + synchronized (STATIC_LOCK) { + if (sInstance == null) { + sInstance = new AccessibilityControllerInternalImpl(service); + } + return sInstance; + } + } + + private final AccessibilityTracing mTracing; + private AccessibilityControllerInternalImpl(WindowManagerService service) { + mTracing = AccessibilityTracing.getInstance(service); + } + + @Override + public void startTrace() { + mTracing.startTrace(); + } + + @Override + public void stopTrace() { + mTracing.stopTrace(); + } + + @Override + public boolean isEnabled() { + return mTracing.isEnabled(); + } + + @Override + public void logTrace( + String where, String callingParams, byte[] a11yDump, int callingUid, + StackTraceElement[] stackTrace) { + mTracing.logState(where, callingParams, a11yDump, callingUid, stackTrace); + } + } + + private static final class AccessibilityTracing { + private static AccessibilityTracing sInstance; + static AccessibilityTracing getInstance(WindowManagerService service) { + synchronized (STATIC_LOCK) { + if (sInstance == null) { + sInstance = new AccessibilityTracing(service); + } + return sInstance; + } + } + + private static final int BUFFER_CAPACITY = 4096 * 1024; + private static final String TRACE_FILENAME = "/data/misc/a11ytrace/a11y_trace.pb"; + private static final String TRACE_DIRECTORY = "/data/misc/a11ytrace/"; + private static final String TAG = "AccessibilityTracing"; + private static final long MAGIC_NUMBER_VALUE = + ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L; + + private final Object mLock = new Object(); + private final WindowManagerService mService; + private final File mTraceFile; + private final TraceBuffer mBuffer; + private final LogHandler mHandler; + private volatile boolean mEnabled; + + AccessibilityTracing(WindowManagerService service) { + mService = service; + mTraceFile = new File(TRACE_FILENAME); + mBuffer = new TraceBuffer(BUFFER_CAPACITY); + HandlerThread workThread = new HandlerThread(TAG); + workThread.start(); + mHandler = new LogHandler(workThread.getLooper()); + } + + /** + * Start the trace. + */ + void startTrace() { + if (IS_USER) { + Slog.e(TAG, "Error: Tracing is not supported on user builds."); + return; + } + synchronized (mLock) { + try { + Files.createDirectories(Paths.get(TRACE_DIRECTORY)); + mTraceFile.createNewFile(); + } catch (Exception e) { + Slog.e(TAG, "Error: Failed to create trace file."); + return; + } + mEnabled = true; + mBuffer.resetBuffer(); + } + } + + /** + * Stops the trace and write the current buffer to disk + */ + void stopTrace() { + if (IS_USER) { + Slog.e(TAG, "Error: Tracing is not supported on user builds."); + return; + } + synchronized (mLock) { + mEnabled = false; + if (mEnabled) { + Slog.e(TAG, "Error: tracing enabled while waiting for flush."); + return; + } + writeTraceToFile(); + } + } + + boolean isEnabled() { + return mEnabled; + } + + /** + * Write an accessibility trace log entry. + */ + void logState(String where) { + if (!mEnabled) { + return; + } + logState(where, ""); + } + + /** + * Write an accessibility trace log entry. + */ + void logState(String where, String callingParams) { + if (!mEnabled) { + return; + } + logState(where, callingParams, "".getBytes()); + } + + /** + * Write an accessibility trace log entry. + */ + void logState(String where, String callingParams, byte[] a11yDump) { + if (!mEnabled) { + return; + } + logState(where, callingParams, a11yDump, Binder.getCallingUid()); + } + + /** + * Write an accessibility trace log entry. + */ + void logState( + String where, String callingParams, byte[] a11yDump, int callingUid) { + if (!mEnabled) { + return; + } + StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); + + logState(where, callingParams, a11yDump, callingUid, stackTraceElements); + } + + /** + * Write an accessibility trace log entry. + */ + void logState(String where, String callingParams, byte[] a11yDump, int callingUid, + StackTraceElement[] stackTrace) { + if (!mEnabled) { + return; + } + + log(where, callingParams, a11yDump, callingUid, stackTrace); + } + + private String toStackTraceString(StackTraceElement[] stackTraceElements) { + if (stackTraceElements == null) { + return ""; + } + StringBuilder stringBuilder = new StringBuilder(); + boolean skip = true; + for (int i = 0; i < stackTraceElements.length; i++) { + if (stackTraceElements[i].toString().contains( + AccessibilityTracing.class.getSimpleName())) { + skip = false; + } else if (!skip) { + stringBuilder.append(stackTraceElements[i].toString()).append("\n"); + } + } + return stringBuilder.toString(); + } + + /** + * Write the current state to the buffer + */ + private void log(String where, String callingParams, byte[] a11yDump, int callingUid, + StackTraceElement[] stackTrace) { + SimpleDateFormat fm = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); + SomeArgs args = SomeArgs.obtain(); + args.arg1 = SystemClock.elapsedRealtimeNanos(); + args.arg2 = fm.format(new Date()).toString(); + args.arg3 = where; + args.arg4 = Process.myPid() + ":" + Application.getProcessName(); + args.arg5 = Thread.currentThread().getId() + ":" + Thread.currentThread().getName(); + args.arg6 = callingUid; + args.arg7 = callingParams; + args.arg8 = stackTrace; + args.arg9 = a11yDump; + mHandler.obtainMessage(LogHandler.MESSAGE_LOG_TRACE_ENTRY, args).sendToTarget(); + } + + /** + * Writes the trace buffer to new file for the bugreport. + */ + void writeTraceToFile() { + mHandler.sendEmptyMessage(LogHandler.MESSAGE_WRITE_FILE); + } + + private class LogHandler extends Handler { + public static final int MESSAGE_LOG_TRACE_ENTRY = 1; + public static final int MESSAGE_WRITE_FILE = 2; + + LogHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message message) { + switch (message.what) { + case MESSAGE_LOG_TRACE_ENTRY: { + final SomeArgs args = (SomeArgs) message.obj; + try { + ProtoOutputStream os = new ProtoOutputStream(); + PackageManagerInternal pmInternal = + LocalServices.getService(PackageManagerInternal.class); + + long tokenOuter = os.start(ENTRY); + String callingStack = + toStackTraceString((StackTraceElement[]) args.arg8); + + os.write(ELAPSED_REALTIME_NANOS, (long) args.arg1); + os.write(CALENDAR_TIME, (String) args.arg2); + os.write(WHERE, (String) args.arg3); + os.write(PROCESS_NAME, (String) args.arg4); + os.write(THREAD_ID_NAME, (String) args.arg5); + os.write(CALLING_PKG, pmInternal.getNameForUid((int) args.arg6)); + os.write(CALLING_PARAMS, (String) args.arg7); + os.write(CALLING_STACKS, callingStack); + os.write(ACCESSIBILITY_SERVICE, (byte[]) args.arg9); + + long tokenInner = os.start(WINDOW_MANAGER_SERVICE); + synchronized (mService.mGlobalLock) { + mService.dumpDebugLocked(os, WindowTraceLogLevel.ALL); + } + os.end(tokenInner); + + os.end(tokenOuter); + synchronized (mLock) { + mBuffer.add(os); + } + } catch (Exception e) { + Slog.e(TAG, "Exception while tracing state", e); + } + break; + } + case MESSAGE_WRITE_FILE: { + synchronized (mLock) { + writeTraceToFileInternal(); + } + break; + } + } + } + } + + /** + * Writes the trace buffer to disk. + */ + private void writeTraceToFileInternal() { + try { + ProtoOutputStream proto = new ProtoOutputStream(); + proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE); + mBuffer.writeTraceToFile(mTraceFile, proto); + } catch (IOException e) { + Slog.e(TAG, "Unable to write buffer to file", e); + } + } + } + } diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java index 582aeb36b00b..10a44987fe7d 100644 --- a/services/core/java/com/android/server/wm/AppTransitionController.java +++ b/services/core/java/com/android/server/wm/AppTransitionController.java @@ -712,8 +712,7 @@ public class AppTransitionController { final AccessibilityController accessibilityController = mDisplayContent.mWmService.mAccessibilityController; if (accessibilityController != null) { - accessibilityController.onAppWindowTransitionLocked( - mDisplayContent.getDisplayId(), transit); + accessibilityController.onAppWindowTransition(mDisplayContent.getDisplayId(), transit); } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 3ab79525de97..2c5b955f323f 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1226,7 +1226,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (mWmService.mAccessibilityController != null) { final int prevDisplayId = prevDc != null ? prevDc.getDisplayId() : INVALID_DISPLAY; - mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(prevDisplayId, + mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(prevDisplayId, getDisplayId()); } } @@ -1850,7 +1850,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } if (mWmService.mAccessibilityController != null) { - mWmService.mAccessibilityController.onRotationChangedLocked(this); + mWmService.mAccessibilityController.onRotationChanged(this); } } @@ -3400,7 +3400,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } void updateAccessibilityOnWindowFocusChanged(AccessibilityController accessibilityController) { - accessibilityController.onWindowFocusChangedNotLocked(getDisplayId()); + accessibilityController.onWindowFocusChangedNot(getDisplayId()); } private static void onWindowFocusChanged(WindowState oldFocus, WindowState newFocus) { @@ -4963,7 +4963,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (!mLocationInParentWindow.equals(x, y)) { mLocationInParentWindow.set(x, y); if (mWmService.mAccessibilityController != null) { - mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(mDisplayId); + mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(mDisplayId); } notifyLocationInParentDisplayChanged(); } diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index 803bec8941a8..de4bdaa57efa 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -47,7 +47,7 @@ public class DockedStackDividerController { mTouchRegion.set(touchRegion); // We need to report touchable region changes to accessibility. if (mDisplayContent.mWmService.mAccessibilityController != null) { - mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked( + mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMoved( mDisplayContent.getDisplayId()); } } diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java index 62c0527dfe1b..0902948bf559 100644 --- a/services/core/java/com/android/server/wm/ShellRoot.java +++ b/services/core/java/com/android/server/wm/ShellRoot.java @@ -191,7 +191,7 @@ public class ShellRoot { } } if (mDisplayContent.mWmService.mAccessibilityController != null) { - mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked( + mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMoved( mDisplayContent.getDisplayId()); } } diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 52ed2788d795..2a5e969f9256 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -164,7 +164,7 @@ public class WindowAnimator { dc.checkAppWindowsReadyToShow(); if (accessibilityController != null) { - accessibilityController.drawMagnifiedRegionBorderIfNeededLocked(displayId, + accessibilityController.drawMagnifiedRegionBorderIfNeeded(displayId, mTransaction); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index a3a9eb773abf..a33b8becb488 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -45,6 +45,41 @@ import java.util.List; */ public abstract class WindowManagerInternal { + /** + * Interface for accessibility features implemented by AccessibilityController inside + * WindowManager. + */ + public interface AccessibilityControllerInternal { + /** + * Enable the accessibility trace logging. + */ + void startTrace(); + + /** + * Disable the accessibility trace logging. + */ + void stopTrace(); + + /** + * Is trace enabled or not. + */ + boolean isEnabled(); + + /** + * Add an accessibility trace entry. + * + * @param where A string to identify this log entry, which can be used to filter/search + * through the tracing file. + * @param callingParams The parameters for the method to be logged. + * @param a11yDump The proto byte array for a11y state when the entry is generated. + * @param callingUid The calling uid. + * @param stackTrace The stack trace, null if not needed. + */ + void logTrace( + String where, String callingParams, byte[] a11yDump, int callingUid, + StackTraceElement[] stackTrace); + } + /** * Interface to receive a callback when the windows reported for * accessibility changed. @@ -206,6 +241,11 @@ public abstract class WindowManagerInternal { default void postCancelDragAndDrop() {} } + /** + * Request the interface to access features implemented by AccessibilityController. + */ + public abstract AccessibilityControllerInternal getAccessibilityController(); + /** * Request that the window manager call * {@link DisplayManagerInternal#performTraversalInTransactionFromWindowManager} diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 6319c80dc9bd..4ff13cd30398 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2170,6 +2170,7 @@ public class WindowManagerService extends IWindowManager.Stub void setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets, Rect visibleInsets, Region touchableRegion) { + int uid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -2195,8 +2196,8 @@ public class WindowManagerService extends IWindowManager.Stub // We need to report touchable region changes to accessibility. if (mAccessibilityController != null) { - mAccessibilityController.onSomeWindowResizedOrMovedLocked( - w.getDisplayContent().getDisplayId()); + mAccessibilityController.onSomeWindowResizedOrMovedWithCallingUid( + uid, w.getDisplayContent().getDisplayId()); } } } @@ -2210,7 +2211,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mAccessibilityController != null) { WindowState window = mWindowMap.get(token); if (window != null) { - mAccessibilityController.onRectangleOnScreenRequestedLocked( + mAccessibilityController.onRectangleOnScreenRequested( window.getDisplayId(), rectangle); } } @@ -2313,8 +2314,8 @@ public class WindowManagerService extends IWindowManager.Stub if (((attrChanges & LayoutParams.ACCESSIBILITY_TITLE_CHANGED) != 0) && (mAccessibilityController != null)) { // No move or resize, but the controller checks for title changes as well - mAccessibilityController.onSomeWindowResizedOrMovedLocked( - win.getDisplayContent().getDisplayId()); + mAccessibilityController.onSomeWindowResizedOrMovedWithCallingUid( + uid, win.getDisplayContent().getDisplayId()); } if ((privateFlagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { @@ -2615,7 +2616,7 @@ public class WindowManagerService extends IWindowManager.Stub win.destroySurface(false, stopped); } if (mAccessibilityController != null) { - mAccessibilityController.onWindowTransitionLocked(win, transit); + mAccessibilityController.onWindowTransition(win, transit); } return focusMayChange; @@ -7154,6 +7155,7 @@ public class WindowManagerService extends IWindowManager.Stub checkCallerOwnsDisplay(displayId); synchronized (mGlobalLock) { + int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { final WindowState win = windowForClientLocked(null, client, false); @@ -7165,8 +7167,8 @@ public class WindowManagerService extends IWindowManager.Stub // Notifies AccessibilityController to re-compute the window observer of // this embedded display if (mAccessibilityController != null) { - mAccessibilityController.handleWindowObserverOfEmbeddedDisplayLocked(displayId, - win); + mAccessibilityController.handleWindowObserverOfEmbeddedDisplay( + displayId, win, uid); } } finally { Binder.restoreCallingIdentity(token); @@ -7531,6 +7533,12 @@ public class WindowManagerService extends IWindowManager.Stub private final class LocalService extends WindowManagerInternal { + @Override + public AccessibilityControllerInternal getAccessibilityController() { + return AccessibilityController.getAccessibilityControllerInternal( + WindowManagerService.this); + } + @Override public void clearSnapshotCache() { synchronized (mGlobalLock) { @@ -7549,7 +7557,7 @@ public class WindowManagerService extends IWindowManager.Stub public void setMagnificationSpec(int displayId, MagnificationSpec spec) { synchronized (mGlobalLock) { if (mAccessibilityController != null) { - mAccessibilityController.setMagnificationSpecLocked(displayId, spec); + mAccessibilityController.setMagnificationSpec(displayId, spec); } else { throw new IllegalStateException("Magnification callbacks not set!"); } @@ -7560,7 +7568,7 @@ public class WindowManagerService extends IWindowManager.Stub public void setForceShowMagnifiableBounds(int displayId, boolean show) { synchronized (mGlobalLock) { if (mAccessibilityController != null) { - mAccessibilityController.setForceShowMagnifiableBoundsLocked(displayId, show); + mAccessibilityController.setForceShowMagnifiableBounds(displayId, show); } else { throw new IllegalStateException("Magnification callbacks not set!"); } @@ -7571,8 +7579,7 @@ public class WindowManagerService extends IWindowManager.Stub public void getMagnificationRegion(int displayId, @NonNull Region magnificationRegion) { synchronized (mGlobalLock) { if (mAccessibilityController != null) { - mAccessibilityController.getMagnificationRegionLocked(displayId, - magnificationRegion); + mAccessibilityController.getMagnificationRegion(displayId, magnificationRegion); } else { throw new IllegalStateException("Magnification callbacks not set!"); } @@ -7588,7 +7595,7 @@ public class WindowManagerService extends IWindowManager.Stub } MagnificationSpec spec = null; if (mAccessibilityController != null) { - spec = mAccessibilityController.getMagnificationSpecForWindowLocked(windowState); + spec = mAccessibilityController.getMagnificationSpecForWindow(windowState); } if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) { return null; @@ -7610,9 +7617,9 @@ public class WindowManagerService extends IWindowManager.Stub mAccessibilityController = new AccessibilityController( WindowManagerService.this); } - boolean result = mAccessibilityController.setMagnificationCallbacksLocked( + boolean result = mAccessibilityController.setMagnificationCallbacks( displayId, callbacks); - if (!mAccessibilityController.hasCallbacksLocked()) { + if (!mAccessibilityController.hasCallbacks()) { mAccessibilityController = null; } return result; @@ -7628,9 +7635,9 @@ public class WindowManagerService extends IWindowManager.Stub WindowManagerService.this); } final boolean result = - mAccessibilityController.setWindowsForAccessibilityCallbackLocked( + mAccessibilityController.setWindowsForAccessibilityCallback( displayId, callback); - if (!mAccessibilityController.hasCallbacksLocked()) { + if (!mAccessibilityController.hasCallbacks()) { mAccessibilityController = null; } return result; @@ -7819,7 +7826,7 @@ public class WindowManagerService extends IWindowManager.Stub accessibilityController = mAccessibilityController; } if (accessibilityController != null) { - accessibilityController.performComputeChangedWindowsNotLocked(displayId, true); + accessibilityController.performComputeChangedWindowsNot(displayId, true); } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 661118ff1990..298e31421461 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2021,7 +2021,7 @@ class WindowState extends WindowContainer implements WindowManagerP final int winTransit = TRANSIT_EXIT; mWinAnimator.applyAnimationLocked(winTransit, false /* isEntrance */); if (accessibilityController != null) { - accessibilityController.onWindowTransitionLocked(this, winTransit); + accessibilityController.onWindowTransition(this, winTransit); } } setDisplayLayoutNeeded(); @@ -2035,7 +2035,7 @@ class WindowState extends WindowContainer implements WindowManagerP if (isVisibleNow()) { mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false); if (mWmService.mAccessibilityController != null) { - mWmService.mAccessibilityController.onWindowTransitionLocked(this, TRANSIT_EXIT); + mWmService.mAccessibilityController.onWindowTransition(this, TRANSIT_EXIT); } changed = true; if (displayContent != null) { @@ -2113,7 +2113,7 @@ class WindowState extends WindowContainer implements WindowManagerP } if (mWmService.mAccessibilityController != null) { - mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(getDisplayId()); + mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(getDisplayId()); } updateLocationInParentDisplayIfNeeded(); @@ -2347,7 +2347,7 @@ class WindowState extends WindowContainer implements WindowManagerP mWmService.requestTraversal(); } if (mWmService.mAccessibilityController != null) { - mWmService.mAccessibilityController.onWindowTransitionLocked(this, transit); + mWmService.mAccessibilityController.onWindowTransition(this, transit); } } final boolean isAnimating = mAnimatingExit || isAnimating(TRANSITION | PARENTS, @@ -3679,7 +3679,7 @@ class WindowState extends WindowContainer implements WindowManagerP displayId); if (mWmService.mAccessibilityController != null) { - mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(displayId); + mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(displayId); } updateLocationInParentDisplayIfNeeded(); } catch (RemoteException e) { @@ -4782,7 +4782,7 @@ class WindowState extends WindowContainer implements WindowManagerP return; } if (mWmService.mAccessibilityController != null) { - mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(getDisplayId()); + mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(getDisplayId()); } if (!isSelfOrAncestorWindowAnimatingExit()) { diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index c8b940a831a8..95660ed572d9 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -946,7 +946,7 @@ class WindowStateAnimator { } if (mService.mAccessibilityController != null) { - mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit); + mService.mAccessibilityController.onWindowTransition(mWin, transit); } } -- cgit v1.2.3-59-g8ed1b