Merge "Allow the use of input features for windowless windows" into udc-dev
This commit is contained in:
@@ -294,7 +294,7 @@ interface IWindowSession {
|
||||
* an input channel where the client can receive input.
|
||||
*/
|
||||
void grantInputChannel(int displayId, in SurfaceControl surface, in IWindow window,
|
||||
in IBinder hostInputToken, int flags, int privateFlags, int type,
|
||||
in IBinder hostInputToken, int flags, int privateFlags, int inputFeatures, int type,
|
||||
in IBinder windowToken, in IBinder focusGrantToken, String inputHandleName,
|
||||
out InputChannel outInputChannel);
|
||||
|
||||
@@ -302,7 +302,8 @@ interface IWindowSession {
|
||||
* Update the flags on an input channel associated with a particular surface.
|
||||
*/
|
||||
oneway void updateInputChannel(in IBinder channelToken, int displayId,
|
||||
in SurfaceControl surface, int flags, int privateFlags, in Region region);
|
||||
in SurfaceControl surface, int flags, int privateFlags, int inputFeatures,
|
||||
in Region region);
|
||||
|
||||
/**
|
||||
* Transfer window focus to an embedded window if the calling window has focus.
|
||||
|
||||
@@ -139,7 +139,7 @@ public class WindowlessWindowManager implements IWindowSession {
|
||||
try {
|
||||
mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
|
||||
state.mSurfaceControl, state.mParams.flags, state.mParams.privateFlags,
|
||||
state.mInputRegion);
|
||||
state.mParams.inputFeatures, state.mInputRegion);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to update surface input channel: ", e);
|
||||
}
|
||||
@@ -189,12 +189,13 @@ public class WindowlessWindowManager implements IWindowSession {
|
||||
mRealWm.grantInputChannel(displayId,
|
||||
new SurfaceControl(sc, "WindowlessWindowManager.addToDisplay"),
|
||||
window, mHostInputToken,
|
||||
attrs.flags, attrs.privateFlags, attrs.type, attrs.token,
|
||||
mFocusGrantToken, attrs.getTitle().toString(), outInputChannel);
|
||||
attrs.flags, attrs.privateFlags, attrs.inputFeatures, attrs.type,
|
||||
attrs.token, mFocusGrantToken, attrs.getTitle().toString(),
|
||||
outInputChannel);
|
||||
} else {
|
||||
mRealWm.grantInputChannel(displayId, sc, window, mHostInputToken, attrs.flags,
|
||||
attrs.privateFlags, attrs.type, attrs.token, mFocusGrantToken,
|
||||
attrs.getTitle().toString(), outInputChannel);
|
||||
attrs.privateFlags, attrs.inputFeatures, attrs.type, attrs.token,
|
||||
mFocusGrantToken, attrs.getTitle().toString(), outInputChannel);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to grant input to surface: ", e);
|
||||
@@ -381,16 +382,19 @@ public class WindowlessWindowManager implements IWindowSession {
|
||||
outMergedConfiguration.setConfiguration(mConfiguration, mConfiguration);
|
||||
}
|
||||
|
||||
if ((attrChanges & WindowManager.LayoutParams.FLAGS_CHANGED) != 0
|
||||
&& state.mInputChannelToken != null) {
|
||||
final int inputChangeMask = WindowManager.LayoutParams.FLAGS_CHANGED
|
||||
| WindowManager.LayoutParams.INPUT_FEATURES_CHANGED;
|
||||
if ((attrChanges & inputChangeMask) != 0 && state.mInputChannelToken != null) {
|
||||
try {
|
||||
if(mRealWm instanceof IWindowSession.Stub) {
|
||||
if (mRealWm instanceof IWindowSession.Stub) {
|
||||
mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
|
||||
new SurfaceControl(sc, "WindowlessWindowManager.relayout"),
|
||||
attrs.flags, attrs.privateFlags, state.mInputRegion);
|
||||
attrs.flags, attrs.privateFlags, attrs.inputFeatures,
|
||||
state.mInputRegion);
|
||||
} else {
|
||||
mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, sc,
|
||||
attrs.flags, attrs.privateFlags, state.mInputRegion);
|
||||
attrs.flags, attrs.privateFlags, attrs.inputFeatures,
|
||||
state.mInputRegion);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to update surface input channel: ", e);
|
||||
@@ -560,14 +564,14 @@ public class WindowlessWindowManager implements IWindowSession {
|
||||
|
||||
@Override
|
||||
public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window,
|
||||
IBinder hostInputToken, int flags, int privateFlags, int type,
|
||||
IBinder hostInputToken, int flags, int privateFlags, int inputFeatures, int type,
|
||||
IBinder windowToken, IBinder focusGrantToken, String inputHandleName,
|
||||
InputChannel outInputChannel) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
|
||||
int flags, int privateFlags, Region region) {
|
||||
int flags, int privateFlags, int inputFeatures, Region region) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -103,6 +103,7 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
null /* hostInputToken */,
|
||||
FLAG_NOT_FOCUSABLE,
|
||||
PRIVATE_FLAG_TRUSTED_OVERLAY,
|
||||
0 /* inputFeatures */,
|
||||
TYPE_APPLICATION,
|
||||
null /* windowToken */,
|
||||
mFocusGrantToken,
|
||||
@@ -208,6 +209,7 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
mDecorationSurface,
|
||||
FLAG_NOT_FOCUSABLE,
|
||||
PRIVATE_FLAG_TRUSTED_OVERLAY,
|
||||
0 /* inputFeatures */,
|
||||
touchRegion);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
|
||||
@@ -857,7 +857,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
|
||||
@Override
|
||||
public void grantInputChannel(int displayId, SurfaceControl surface,
|
||||
IWindow window, IBinder hostInputToken, int flags, int privateFlags, int type,
|
||||
IBinder windowToken, IBinder focusGrantToken, String inputHandleName,
|
||||
int inputFeatures, IBinder windowToken, IBinder focusGrantToken, String inputHandleName,
|
||||
InputChannel outInputChannel) {
|
||||
if (hostInputToken == null && !mCanAddInternalSystemWindow) {
|
||||
// Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
|
||||
@@ -869,7 +869,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
|
||||
try {
|
||||
mService.grantInputChannel(this, mUid, mPid, displayId, surface, window, hostInputToken,
|
||||
flags, mCanAddInternalSystemWindow ? privateFlags : 0,
|
||||
type, windowToken, focusGrantToken, inputHandleName,
|
||||
type, inputFeatures, windowToken, focusGrantToken, inputHandleName,
|
||||
outInputChannel);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
@@ -878,11 +878,11 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
|
||||
|
||||
@Override
|
||||
public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
|
||||
int flags, int privateFlags, Region region) {
|
||||
int flags, int privateFlags, int inputFeatures, Region region) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mService.updateInputChannel(channelToken, displayId, surface, flags,
|
||||
mCanAddInternalSystemWindow ? privateFlags : 0, region);
|
||||
mCanAddInternalSystemWindow ? privateFlags : 0, inputFeatures, region);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
|
||||
@@ -8571,8 +8571,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
*/
|
||||
void grantInputChannel(Session session, int callingUid, int callingPid, int displayId,
|
||||
SurfaceControl surface, IWindow window, IBinder hostInputToken,
|
||||
int flags, int privateFlags, int type, IBinder windowToken, IBinder focusGrantToken,
|
||||
String inputHandleName, InputChannel outInputChannel) {
|
||||
int flags, int privateFlags, int inputFeatures, int type, IBinder windowToken,
|
||||
IBinder focusGrantToken, String inputHandleName, InputChannel outInputChannel) {
|
||||
final int sanitizedType = sanitizeWindowType(session, displayId, windowToken, type);
|
||||
final InputApplicationHandle applicationHandle;
|
||||
final String name;
|
||||
@@ -8589,7 +8589,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface,
|
||||
name, applicationHandle, flags, privateFlags, sanitizedType,
|
||||
name, applicationHandle, flags, privateFlags, inputFeatures, sanitizedType,
|
||||
null /* region */, window);
|
||||
|
||||
clientChannel.copyTo(outInputChannel);
|
||||
@@ -8630,13 +8630,14 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
|
||||
int displayId, SurfaceControl surface, String name,
|
||||
InputApplicationHandle applicationHandle, int flags,
|
||||
int privateFlags, int type, Region region, IWindow window) {
|
||||
int privateFlags, int inputFeatures, int type, Region region, IWindow window) {
|
||||
final InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
|
||||
h.token = channelToken;
|
||||
h.setWindowToken(window);
|
||||
h.name = name;
|
||||
|
||||
flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid);
|
||||
inputFeatures = sanitizeSpyWindow(inputFeatures, name, callingUid, callingPid);
|
||||
|
||||
final int sanitizedLpFlags =
|
||||
(flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE))
|
||||
@@ -8646,7 +8647,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
|
||||
// Do not allow any input features to be set without sanitizing them first.
|
||||
h.inputConfig = InputConfigAdapter.getInputConfigFromWindowParams(
|
||||
type, sanitizedLpFlags, 0 /*inputFeatures*/);
|
||||
type, sanitizedLpFlags, inputFeatures);
|
||||
|
||||
|
||||
if ((flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
|
||||
@@ -8683,7 +8684,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
* is undefined.
|
||||
*/
|
||||
void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
|
||||
int flags, int privateFlags, Region region) {
|
||||
int flags, int privateFlags, int inputFeatures, Region region) {
|
||||
final InputApplicationHandle applicationHandle;
|
||||
final String name;
|
||||
final EmbeddedWindowController.EmbeddedWindow win;
|
||||
@@ -8698,7 +8699,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name,
|
||||
applicationHandle, flags, privateFlags, win.mWindowType, region, win.mClient);
|
||||
applicationHandle, flags, privateFlags, inputFeatures, win.mWindowType, region,
|
||||
win.mClient);
|
||||
}
|
||||
|
||||
/** Return whether layer tracing is enabled */
|
||||
|
||||
@@ -26,7 +26,10 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLI
|
||||
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.Display.FLAG_OWN_FOCUS;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY;
|
||||
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||
@@ -49,11 +52,13 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -67,12 +72,16 @@ import android.hardware.display.VirtualDisplay;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.InputConfig;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.MergedConfiguration;
|
||||
import android.view.IWindow;
|
||||
import android.view.IWindowSessionCallback;
|
||||
import android.view.InputChannel;
|
||||
import android.view.InsetsSourceControl;
|
||||
import android.view.InsetsState;
|
||||
import android.view.Surface;
|
||||
@@ -690,6 +699,102 @@ public class WindowManagerServiceTests extends WindowTestsBase {
|
||||
assertEquals(validRect, resultingArgs.mSourceCrop);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantInputChannel_sanitizeSpyWindowForApplications() {
|
||||
final Session session = mock(Session.class);
|
||||
final int callingUid = Process.FIRST_APPLICATION_UID;
|
||||
final int callingPid = 1234;
|
||||
final SurfaceControl surfaceControl = mock(SurfaceControl.class);
|
||||
final IWindow window = mock(IWindow.class);
|
||||
final IBinder windowToken = mock(IBinder.class);
|
||||
when(window.asBinder()).thenReturn(windowToken);
|
||||
final IBinder focusGrantToken = mock(IBinder.class);
|
||||
|
||||
final InputChannel inputChannel = new InputChannel();
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY,
|
||||
surfaceControl, window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE,
|
||||
PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY, TYPE_APPLICATION,
|
||||
null /* windowToken */, focusGrantToken, "TestInputChannel",
|
||||
inputChannel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantInputChannel_allowSpyWindowForInputMonitorPermission() {
|
||||
final Session session = mock(Session.class);
|
||||
final int callingUid = Process.SYSTEM_UID;
|
||||
final int callingPid = 1234;
|
||||
final SurfaceControl surfaceControl = mock(SurfaceControl.class);
|
||||
final IWindow window = mock(IWindow.class);
|
||||
final IBinder windowToken = mock(IBinder.class);
|
||||
when(window.asBinder()).thenReturn(windowToken);
|
||||
final IBinder focusGrantToken = mock(IBinder.class);
|
||||
|
||||
final InputChannel inputChannel = new InputChannel();
|
||||
mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY, surfaceControl,
|
||||
window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY,
|
||||
INPUT_FEATURE_SPY, TYPE_APPLICATION, null /* windowToken */, focusGrantToken,
|
||||
"TestInputChannel", inputChannel);
|
||||
|
||||
verify(mTransaction).setInputWindowInfo(
|
||||
eq(surfaceControl),
|
||||
argThat(h -> (h.inputConfig & InputConfig.SPY) == InputConfig.SPY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateInputChannel_sanitizeSpyWindowForApplications() {
|
||||
final Session session = mock(Session.class);
|
||||
final int callingUid = Process.FIRST_APPLICATION_UID;
|
||||
final int callingPid = 1234;
|
||||
final SurfaceControl surfaceControl = mock(SurfaceControl.class);
|
||||
final IWindow window = mock(IWindow.class);
|
||||
final IBinder windowToken = mock(IBinder.class);
|
||||
when(window.asBinder()).thenReturn(windowToken);
|
||||
final IBinder focusGrantToken = mock(IBinder.class);
|
||||
|
||||
final InputChannel inputChannel = new InputChannel();
|
||||
mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY, surfaceControl,
|
||||
window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY,
|
||||
0 /* inputFeatures */, TYPE_APPLICATION, null /* windowToken */, focusGrantToken,
|
||||
"TestInputChannel", inputChannel);
|
||||
verify(mTransaction).setInputWindowInfo(
|
||||
eq(surfaceControl),
|
||||
argThat(h -> (h.inputConfig & InputConfig.SPY) == 0));
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
|
||||
FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY,
|
||||
null /* region */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateInputChannel_allowSpyWindowForInputMonitorPermission() {
|
||||
final Session session = mock(Session.class);
|
||||
final int callingUid = Process.SYSTEM_UID;
|
||||
final int callingPid = 1234;
|
||||
final SurfaceControl surfaceControl = mock(SurfaceControl.class);
|
||||
final IWindow window = mock(IWindow.class);
|
||||
final IBinder windowToken = mock(IBinder.class);
|
||||
when(window.asBinder()).thenReturn(windowToken);
|
||||
final IBinder focusGrantToken = mock(IBinder.class);
|
||||
|
||||
final InputChannel inputChannel = new InputChannel();
|
||||
mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY, surfaceControl,
|
||||
window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY,
|
||||
0 /* inputFeatures */, TYPE_APPLICATION, null /* windowToken */, focusGrantToken,
|
||||
"TestInputChannel", inputChannel);
|
||||
verify(mTransaction).setInputWindowInfo(
|
||||
eq(surfaceControl),
|
||||
argThat(h -> (h.inputConfig & InputConfig.SPY) == 0));
|
||||
|
||||
mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
|
||||
FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY,
|
||||
null /* region */);
|
||||
verify(mTransaction).setInputWindowInfo(
|
||||
eq(surfaceControl),
|
||||
argThat(h -> (h.inputConfig & InputConfig.SPY) == InputConfig.SPY));
|
||||
}
|
||||
|
||||
private void setupActivityWithLaunchCookie(IBinder launchCookie, WindowContainerToken wct) {
|
||||
final WindowContainer.RemoteToken remoteToken = mock(WindowContainer.RemoteToken.class);
|
||||
when(remoteToken.toWindowContainerToken()).thenReturn(wct);
|
||||
|
||||
Reference in New Issue
Block a user