Merge changes from topic "overlay"
* changes: Create display accessibility overlay API. Expose SurfacePackage#getSurfaceControl
This commit is contained in:
@@ -3087,6 +3087,7 @@ package android.accessibilityservice {
|
||||
|
||||
public abstract class AccessibilityService extends android.app.Service {
|
||||
ctor public AccessibilityService();
|
||||
method public void attachAccessibilityOverlayToDisplay(int, @NonNull android.view.SurfaceControl);
|
||||
method public boolean clearCache();
|
||||
method public boolean clearCachedSubtree(@NonNull android.view.accessibility.AccessibilityNodeInfo);
|
||||
method public final void disableSelf();
|
||||
@@ -49980,6 +49981,7 @@ package android.view {
|
||||
public static final class SurfaceControlViewHost.SurfacePackage implements android.os.Parcelable {
|
||||
ctor public SurfaceControlViewHost.SurfacePackage(@NonNull android.view.SurfaceControlViewHost.SurfacePackage);
|
||||
method public int describeContents();
|
||||
method @NonNull public android.view.SurfaceControl getSurfaceControl();
|
||||
method public void notifyConfigurationChanged(@NonNull android.content.res.Configuration);
|
||||
method public void notifyDetachedFromWindow();
|
||||
method public void release();
|
||||
|
||||
@@ -56,7 +56,7 @@ import android.util.SparseArray;
|
||||
import android.view.Display;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManagerImpl;
|
||||
import android.view.accessibility.AccessibilityCache;
|
||||
@@ -2467,8 +2467,8 @@ public abstract class AccessibilityService extends Service {
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>Note:</strong> If the view with {@link AccessibilityNodeInfo#FOCUS_INPUT}
|
||||
* is on an embedded view hierarchy which is embedded in a {@link SurfaceView} via
|
||||
* {@link SurfaceView#setChildSurfacePackage}, there is a limitation that this API
|
||||
* is on an embedded view hierarchy which is embedded in a {@link android.view.SurfaceView} via
|
||||
* {@link android.view.SurfaceView#setChildSurfacePackage}, there is a limitation that this API
|
||||
* won't be able to find the node for the view. It's because views don't know about
|
||||
* the embedded hierarchies. Instead, you could traverse all the nodes to find the
|
||||
* focus.
|
||||
@@ -3379,4 +3379,28 @@ public abstract class AccessibilityService extends Service {
|
||||
controller.onStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a {@link android.view.SurfaceControl} containing an accessibility overlay to the
|
||||
* specified display. This type of overlay should be used for content that does not need to
|
||||
* track the location and size of Views in the currently active app e.g. service configuration
|
||||
* or general service UI. To remove this overlay and free the associated resources, use
|
||||
* <code> new SurfaceControl.Transaction().reparent(sc, null).apply();</code>.
|
||||
*
|
||||
* @param displayId the display to which the SurfaceControl should be attached.
|
||||
* @param sc the SurfaceControl containing the overlay content
|
||||
*/
|
||||
public void attachAccessibilityOverlayToDisplay(int displayId, @NonNull SurfaceControl sc) {
|
||||
Preconditions.checkNotNull(sc, "SurfaceControl cannot be null");
|
||||
final IAccessibilityServiceConnection connection =
|
||||
AccessibilityInteractionClient.getConnection(mConnectionId);
|
||||
if (connection == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
connection.attachAccessibilityOverlayToDisplay(displayId, sc);
|
||||
} catch (RemoteException re) {
|
||||
throw new RuntimeException(re);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.os.Bundle;
|
||||
import android.os.RemoteCallback;
|
||||
import android.view.MagnificationSpec;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
|
||||
@@ -155,4 +156,5 @@ interface IAccessibilityServiceConnection {
|
||||
void setInstalledAndEnabledServices(in List<AccessibilityServiceInfo> infos);
|
||||
|
||||
List<AccessibilityServiceInfo> getInstalledAndEnabledServices();
|
||||
void attachAccessibilityOverlayToDisplay(int displayId, in SurfaceControl sc);
|
||||
}
|
||||
|
||||
@@ -159,9 +159,11 @@ public class SurfaceControlViewHost {
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link SurfaceView#setChildSurfacePackage} or manually fix
|
||||
* accessibility (see SurfaceView implementation).
|
||||
* @hide
|
||||
* Returns the {@link android.view.SurfaceControl} associated with this SurfacePackage for
|
||||
* cases where more control is required.
|
||||
*
|
||||
* @return the SurfaceControl associated with this SurfacePackage and its containing
|
||||
* SurfaceControlViewHost
|
||||
*/
|
||||
public @NonNull SurfaceControl getSurfaceControl() {
|
||||
return mSurfaceControl;
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.ScreenCapture;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -222,4 +223,7 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon
|
||||
public List<AccessibilityServiceInfo> getInstalledAndEnabledServices() throws RemoteException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachAccessibilityOverlayToDisplay(int displayId, SurfaceControl sc) {}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ import android.util.SparseArray;
|
||||
import android.view.Display;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MagnificationSpec;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.View;
|
||||
import android.view.WindowInfo;
|
||||
import android.view.accessibility.AccessibilityCache;
|
||||
@@ -289,6 +290,8 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
|
||||
void requestImeLocked(AbstractAccessibilityServiceConnection connection);
|
||||
|
||||
void unbindImeLocked(AbstractAccessibilityServiceConnection connection);
|
||||
|
||||
void attachAccessibilityOverlayToDisplay(int displayId, SurfaceControl sc);
|
||||
}
|
||||
|
||||
public AbstractAccessibilityServiceConnection(Context context, ComponentName componentName,
|
||||
@@ -2486,4 +2489,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
|
||||
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachAccessibilityOverlayToDisplay(int displayId, SurfaceControl sc) {
|
||||
mSystemSupport.attachAccessibilityOverlayToDisplay(displayId, sc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ import android.view.IWindow;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MagnificationSpec;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowInfo;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
@@ -291,12 +292,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
|
||||
private Point mTempPoint = new Point();
|
||||
private boolean mIsAccessibilityButtonShown;
|
||||
|
||||
private boolean mInputBound;
|
||||
IRemoteAccessibilityInputConnection mRemoteInputConnection;
|
||||
EditorInfo mEditorInfo;
|
||||
boolean mRestarting;
|
||||
boolean mInputSessionRequested;
|
||||
private SparseArray<SurfaceControl> mA11yOverlayLayers = new SparseArray<>();
|
||||
|
||||
private AccessibilityUserState getCurrentUserStateLocked() {
|
||||
return getUserStateLocked(mCurrentUserId);
|
||||
@@ -3967,6 +3968,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
|
||||
synchronized (mLock) {
|
||||
mDisplaysList.add(display);
|
||||
mA11yOverlayLayers.put(
|
||||
displayId, mWindowManagerService.getA11yOverlayLayer(displayId));
|
||||
if (mInputFilter != null) {
|
||||
mInputFilter.onDisplayAdded(display);
|
||||
}
|
||||
@@ -3990,6 +3993,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
if (!removeDisplayFromList(displayId)) {
|
||||
return;
|
||||
}
|
||||
mA11yOverlayLayers.remove(displayId);
|
||||
if (mInputFilter != null) {
|
||||
mInputFilter.onDisplayRemoved(displayId);
|
||||
}
|
||||
@@ -4691,4 +4695,30 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachAccessibilityOverlayToDisplay(int displayId, SurfaceControl sc) {
|
||||
mMainHandler.sendMessage(
|
||||
obtainMessage(
|
||||
AccessibilityManagerService::attachAccessibilityOverlayToDisplayInternal,
|
||||
this,
|
||||
displayId,
|
||||
sc));
|
||||
}
|
||||
|
||||
void attachAccessibilityOverlayToDisplayInternal(int displayId, SurfaceControl sc) {
|
||||
if (!mA11yOverlayLayers.contains(displayId)) {
|
||||
mA11yOverlayLayers.put(displayId, mWindowManagerService.getA11yOverlayLayer(displayId));
|
||||
}
|
||||
SurfaceControl parent = mA11yOverlayLayers.get(displayId);
|
||||
if (parent == null) {
|
||||
Slog.e(LOG_TAG, "Unable to get accessibility overlay SurfaceControl.");
|
||||
mA11yOverlayLayers.remove(displayId);
|
||||
return;
|
||||
}
|
||||
SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
|
||||
transaction.reparent(sc, parent);
|
||||
transaction.apply();
|
||||
transaction.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,6 +311,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
*/
|
||||
private SurfaceControl mOverlayLayer;
|
||||
|
||||
/** A surfaceControl specifically for accessibility overlays. */
|
||||
private SurfaceControl mA11yOverlayLayer;
|
||||
|
||||
/**
|
||||
* The direct child layer of the display to put all non-overlay windows. This is also used for
|
||||
* screen rotation animation so that there is a parent layer to put the animation leash.
|
||||
@@ -1269,12 +1272,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
transaction.reparent(mOverlayLayer, mSurfaceControl);
|
||||
}
|
||||
|
||||
if (mA11yOverlayLayer == null) {
|
||||
mA11yOverlayLayer =
|
||||
b.setName("Accessibility Overlays").setParent(mSurfaceControl).build();
|
||||
} else {
|
||||
transaction.reparent(mA11yOverlayLayer, mSurfaceControl);
|
||||
}
|
||||
|
||||
transaction
|
||||
.setLayer(mSurfaceControl, 0)
|
||||
.setLayerStack(mSurfaceControl, mDisplayId)
|
||||
.show(mSurfaceControl)
|
||||
.setLayer(mOverlayLayer, Integer.MAX_VALUE)
|
||||
.show(mOverlayLayer);
|
||||
.show(mOverlayLayer)
|
||||
.setLayer(mA11yOverlayLayer, Integer.MAX_VALUE - 1)
|
||||
.show(mA11yOverlayLayer);
|
||||
}
|
||||
|
||||
boolean isReady() {
|
||||
@@ -3250,6 +3262,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
setRemoteInsetsController(null);
|
||||
mWmService.mAnimator.removeDisplayLocked(mDisplayId);
|
||||
mOverlayLayer.release();
|
||||
mA11yOverlayLayer.release();
|
||||
mWindowingLayer.release();
|
||||
mInputMonitor.onDisplayRemoved();
|
||||
mWmService.mDisplayNotificationController.dispatchDisplayRemoved(this);
|
||||
@@ -5502,6 +5515,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
return mOverlayLayer;
|
||||
}
|
||||
|
||||
SurfaceControl getA11yOverlayLayer() {
|
||||
return mA11yOverlayLayer;
|
||||
}
|
||||
|
||||
SurfaceControl[] findRoundedCornerOverlays() {
|
||||
List<SurfaceControl> roundedCornerOverlays = new ArrayList<>();
|
||||
for (WindowToken token : mTokenMap.values()) {
|
||||
|
||||
@@ -903,4 +903,7 @@ public abstract class WindowManagerInternal {
|
||||
* could not be prepared and the session needs to be torn down.
|
||||
*/
|
||||
public abstract boolean setContentRecordingSession(ContentRecordingSession incomingSession);
|
||||
|
||||
/** Returns the SurfaceControl accessibility services should use for accessibility overlays. */
|
||||
public abstract SurfaceControl getA11yOverlayLayer(int displayId);
|
||||
}
|
||||
|
||||
@@ -736,7 +736,6 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
|
||||
@VisibleForTesting
|
||||
final ContentRecordingController mContentRecordingController = new ContentRecordingController();
|
||||
|
||||
@VisibleForTesting
|
||||
final class SettingsObserver extends ContentObserver {
|
||||
private final Uri mDisplayInversionEnabledUri =
|
||||
@@ -8301,6 +8300,17 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceControl getA11yOverlayLayer(int displayId) {
|
||||
synchronized (mGlobalLock) {
|
||||
DisplayContent dc = mRoot.getDisplayContent(displayId);
|
||||
if (dc != null) {
|
||||
return dc.getA11yOverlayLayer();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void registerAppFreezeListener(AppFreezeListener listener) {
|
||||
|
||||
Reference in New Issue
Block a user