Merge "Optionally wait animations on syncInputTransactions/injectInputEvent"
This commit is contained in:
committed by
Android (Google) Code Review
commit
f48a5e3d13
@@ -302,8 +302,10 @@ package android.app {
|
||||
method public void destroy();
|
||||
method @NonNull public android.os.ParcelFileDescriptor[] executeShellCommandRwe(@NonNull String);
|
||||
method @Deprecated public boolean grantRuntimePermission(String, String, android.os.UserHandle);
|
||||
method public boolean injectInputEvent(@NonNull android.view.InputEvent, boolean, boolean);
|
||||
method @Deprecated public boolean revokeRuntimePermission(String, String, android.os.UserHandle);
|
||||
method public void syncInputTransactions();
|
||||
method public void syncInputTransactions(boolean);
|
||||
}
|
||||
|
||||
public class UiModeManager {
|
||||
|
||||
@@ -36,8 +36,8 @@ import android.os.ParcelFileDescriptor;
|
||||
interface IUiAutomationConnection {
|
||||
void connect(IAccessibilityServiceClient client, int flags);
|
||||
void disconnect();
|
||||
boolean injectInputEvent(in InputEvent event, boolean sync);
|
||||
void syncInputTransactions();
|
||||
boolean injectInputEvent(in InputEvent event, boolean sync, boolean waitForAnimations);
|
||||
void syncInputTransactions(boolean waitForAnimations);
|
||||
boolean setRotation(int rotation);
|
||||
Bitmap takeScreenshot(in Rect crop);
|
||||
boolean clearWindowContentFrameStats(int windowId);
|
||||
|
||||
@@ -1119,7 +1119,8 @@ public class Instrumentation {
|
||||
}
|
||||
try {
|
||||
WindowManagerGlobal.getWindowManagerService().injectInputAfterTransactionsApplied(event,
|
||||
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
|
||||
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH,
|
||||
true /* waitForAnimations */);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,6 +695,9 @@ public final class UiAutomation {
|
||||
|
||||
/**
|
||||
* A method for injecting an arbitrary input event.
|
||||
*
|
||||
* This method waits for all window container animations and surface operations to complete.
|
||||
*
|
||||
* <p>
|
||||
* <strong>Note:</strong> It is caller's responsibility to recycle the event.
|
||||
* </p>
|
||||
@@ -704,12 +707,34 @@ public final class UiAutomation {
|
||||
* @return Whether event injection succeeded.
|
||||
*/
|
||||
public boolean injectInputEvent(InputEvent event, boolean sync) {
|
||||
return injectInputEvent(event, sync, true /* waitForAnimations */);
|
||||
}
|
||||
|
||||
/**
|
||||
* A method for injecting an arbitrary input event, optionally waiting for window animations to
|
||||
* complete.
|
||||
* <p>
|
||||
* <strong>Note:</strong> It is caller's responsibility to recycle the event.
|
||||
* </p>
|
||||
*
|
||||
* @param event The event to inject.
|
||||
* @param sync Whether to inject the event synchronously.
|
||||
* @param waitForAnimations Whether to wait for all window container animations and surface
|
||||
* operations to complete.
|
||||
* @return Whether event injection succeeded.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public boolean injectInputEvent(@NonNull InputEvent event, boolean sync,
|
||||
boolean waitForAnimations) {
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "Injecting: " + event + " sync: " + sync);
|
||||
Log.i(LOG_TAG, "Injecting: " + event + " sync: " + sync + " waitForAnimations: "
|
||||
+ waitForAnimations);
|
||||
}
|
||||
// Calling out without a lock held.
|
||||
return mUiAutomationConnection.injectInputEvent(event, sync);
|
||||
return mUiAutomationConnection.injectInputEvent(event, sync, waitForAnimations);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error while injecting input event!", re);
|
||||
}
|
||||
@@ -726,7 +751,26 @@ public final class UiAutomation {
|
||||
public void syncInputTransactions() {
|
||||
try {
|
||||
// Calling out without a lock held.
|
||||
mUiAutomationConnection.syncInputTransactions();
|
||||
mUiAutomationConnection.syncInputTransactions(true /* waitForAnimations */);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error while syncing input transactions!", re);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A request for WindowManagerService to wait until all input information has been sent from
|
||||
* WindowManager to native InputManager and optionally wait for animations to complete.
|
||||
*
|
||||
* @param waitForAnimations Whether to wait for all window container animations and surface
|
||||
* operations to complete.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void syncInputTransactions(boolean waitForAnimations) {
|
||||
try {
|
||||
// Calling out without a lock held.
|
||||
mUiAutomationConnection.syncInputTransactions(waitForAnimations);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error while syncing input transactions!", re);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean injectInputEvent(InputEvent event, boolean sync) {
|
||||
public boolean injectInputEvent(InputEvent event, boolean sync, boolean waitForAnimations) {
|
||||
synchronized (mLock) {
|
||||
throwIfCalledByNotTrustedUidLocked();
|
||||
throwIfShutdownLocked();
|
||||
@@ -134,7 +134,8 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
|
||||
: InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return mWindowManager.injectInputAfterTransactionsApplied(event, mode);
|
||||
return mWindowManager.injectInputAfterTransactionsApplied(event, mode,
|
||||
waitForAnimations);
|
||||
} catch (RemoteException e) {
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
@@ -143,7 +144,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncInputTransactions() {
|
||||
public void syncInputTransactions(boolean waitForAnimations) {
|
||||
synchronized (mLock) {
|
||||
throwIfCalledByNotTrustedUidLocked();
|
||||
throwIfShutdownLocked();
|
||||
@@ -151,12 +152,11 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
|
||||
}
|
||||
|
||||
try {
|
||||
mWindowManager.syncInputTransactions();
|
||||
mWindowManager.syncInputTransactions(waitForAnimations);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setRotation(int rotation) {
|
||||
synchronized (mLock) {
|
||||
|
||||
@@ -668,22 +668,24 @@ interface IWindowManager
|
||||
void setShouldShowIme(int displayId, boolean shouldShow);
|
||||
|
||||
/**
|
||||
* Waits for transactions to get applied before injecting input.
|
||||
* This includes waiting for the input windows to get sent to InputManager.
|
||||
* Waits for transactions to get applied before injecting input, optionally waiting for
|
||||
* animations to complete. This includes waiting for the input windows to get sent to
|
||||
* InputManager.
|
||||
*
|
||||
* This is needed for testing since the system add windows and injects input
|
||||
* quick enough that the windows don't have time to get sent to InputManager.
|
||||
*/
|
||||
boolean injectInputAfterTransactionsApplied(in InputEvent ev, int mode);
|
||||
boolean injectInputAfterTransactionsApplied(in InputEvent ev, int mode,
|
||||
boolean waitForAnimations);
|
||||
|
||||
/**
|
||||
* Waits until all animations have completed and input information has been sent from
|
||||
* WindowManager to native InputManager.
|
||||
* Waits until input information has been sent from WindowManager to native InputManager,
|
||||
* optionally waiting for animations to complete.
|
||||
*
|
||||
* This is needed for testing since we need to ensure input information has been propagated to
|
||||
* native InputManager before proceeding with tests.
|
||||
*/
|
||||
void syncInputTransactions();
|
||||
void syncInputTransactions(boolean waitForAnimations);
|
||||
|
||||
/**
|
||||
* Returns whether SurfaceFlinger layer tracing is enabled.
|
||||
|
||||
@@ -2978,7 +2978,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
displayContent, true /* includingParents */);
|
||||
}
|
||||
}
|
||||
syncInputTransactions();
|
||||
syncInputTransactions(true /* waitForAnimations */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7979,7 +7979,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean injectInputAfterTransactionsApplied(InputEvent ev, int mode) {
|
||||
public boolean injectInputAfterTransactionsApplied(InputEvent ev, int mode,
|
||||
boolean waitForAnimations) {
|
||||
boolean isDown;
|
||||
boolean isUp;
|
||||
|
||||
@@ -7998,21 +7999,23 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
// For all mouse events, also sync before injecting.
|
||||
// For ACTION_UP, sync after injecting.
|
||||
if (isDown || isMouseEvent) {
|
||||
syncInputTransactions();
|
||||
syncInputTransactions(waitForAnimations);
|
||||
}
|
||||
final boolean result =
|
||||
LocalServices.getService(InputManagerInternal.class).injectInputEvent(ev, mode);
|
||||
if (isUp) {
|
||||
syncInputTransactions();
|
||||
syncInputTransactions(waitForAnimations);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncInputTransactions() {
|
||||
public void syncInputTransactions(boolean waitForAnimations) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
waitForAnimationsToComplete();
|
||||
if (waitForAnimations) {
|
||||
waitForAnimationsToComplete();
|
||||
}
|
||||
|
||||
// Collect all input transactions from all displays to make sure we could sync all input
|
||||
// windows at same time.
|
||||
|
||||
Reference in New Issue
Block a user