diff options
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<DisplayMagnifier> mDisplayMagnifiers = new SparseArray<>(); - private SparseArray<WindowsForAccessibilityObserver> 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<WindowState> 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<WindowState> outWindows) { + private void populateWindowsOnScreen(SparseArray<WindowState> 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<WindowState> visibleWindows = mTempWindowStates; - populateVisibleWindowsOnScreenLocked(visibleWindows); + populateVisibleWindowsOnScreen(visibleWindows); Set<IBinder> 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<WindowState> outWindows) { + private void populateVisibleWindowsOnScreen(SparseArray<WindowState> outWindows) { final List<WindowState> 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 4575cf7e9060..9ca7eca07dc6 100644 --- a/services/core/java/com/android/server/wm/AppTransitionController.java +++ b/services/core/java/com/android/server/wm/AppTransitionController.java @@ -724,8 +724,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 1a0e16b9c771..91a6664e0b36 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 eed3299cc93d..2c92fd035def 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -48,6 +48,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. */ @@ -224,6 +259,11 @@ public abstract class WindowManagerInternal { } /** + * Request the interface to access features implemented by AccessibilityController. + */ + public abstract AccessibilityControllerInternal getAccessibilityController(); + + /** * Request that the window manager call * {@link DisplayManagerInternal#performTraversalInTransactionFromWindowManager} * within a surface transaction at a later time. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8965cab0b725..0894b2660769 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2176,6 +2176,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) { @@ -2201,8 +2202,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()); } } } @@ -2216,7 +2217,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); } } @@ -2319,8 +2320,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) { @@ -2620,7 +2621,7 @@ public class WindowManagerService extends IWindowManager.Stub win.destroySurface(false, stopped); } if (mAccessibilityController != null) { - mAccessibilityController.onWindowTransitionLocked(win, transit); + mAccessibilityController.onWindowTransition(win, transit); } return focusMayChange; @@ -7151,6 +7152,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); @@ -7162,8 +7164,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); @@ -7529,6 +7531,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) { mTaskSnapshotController.clearSnapshotCache(); @@ -7546,7 +7554,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!"); } @@ -7557,7 +7565,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!"); } @@ -7568,8 +7576,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!"); } @@ -7585,7 +7592,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; @@ -7607,9 +7614,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; @@ -7625,9 +7632,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; @@ -7825,7 +7832,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 89cb163d5a55..c1f2d02804ea 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2020,7 +2020,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final int winTransit = TRANSIT_EXIT; mWinAnimator.applyAnimationLocked(winTransit, false /* isEntrance */); if (accessibilityController != null) { - accessibilityController.onWindowTransitionLocked(this, winTransit); + accessibilityController.onWindowTransition(this, winTransit); } } setDisplayLayoutNeeded(); @@ -2034,7 +2034,7 @@ class WindowState extends WindowContainer<WindowState> 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) { @@ -2112,7 +2112,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } if (mWmService.mAccessibilityController != null) { - mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(getDisplayId()); + mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(getDisplayId()); } updateLocationInParentDisplayIfNeeded(); @@ -2345,7 +2345,7 @@ class WindowState extends WindowContainer<WindowState> 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, @@ -3672,7 +3672,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP displayId); if (mWmService.mAccessibilityController != null) { - mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(displayId); + mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(displayId); } updateLocationInParentDisplayIfNeeded(); } catch (RemoteException e) { @@ -4775,7 +4775,7 @@ class WindowState extends WindowContainer<WindowState> 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 d164f30fde2c..2da3dda831e1 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -817,7 +817,7 @@ class WindowStateAnimator { } if (mService.mAccessibilityController != null) { - mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit); + mService.mAccessibilityController.onWindowTransition(mWin, transit); } } |