Merge "Migrate Tap exclusion logic to TaskEmbedder." into rvc-dev am: 73cc6b8f47 am: 9eeb721848 am: edb5fb4b6d

Change-Id: I9506306821a97db71d1879372e791af3f2e8c838
This commit is contained in:
Yuncheol Heo
2020-05-06 00:54:37 +00:00
committed by Automerger Merge Worker
3 changed files with 76 additions and 57 deletions

View File

@@ -36,11 +36,14 @@ import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region; import android.graphics.Region;
import android.hardware.display.VirtualDisplay; import android.hardware.display.VirtualDisplay;
import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.view.IWindow; import android.view.IWindow;
import android.view.IWindowManager; import android.view.IWindowManager;
import android.view.IWindowSession;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.WindowManagerGlobal;
import dalvik.system.CloseGuard; import dalvik.system.CloseGuard;
@@ -184,31 +187,45 @@ public abstract class TaskEmbedder {
/** /**
* Called when the task embedder should be initialized. * Called when the task embedder should be initialized.
* NOTE: all overriding methods should call this one after they finish their initialization.
* @return whether to report whether the embedder was initialized. * @return whether to report whether the embedder was initialized.
*/ */
public abstract boolean onInitialize(); public boolean onInitialize() {
updateLocationAndTapExcludeRegion();
return true;
}
/** /**
* Called when the task embedder should be released. * Called when the task embedder should be released.
* @return whether to report whether the embedder was released. * @return whether to report whether the embedder was released.
*/ */
protected abstract boolean onRelease(); protected boolean onRelease() {
// Clear tap-exclude region (if any) for this window.
clearTapExcludeRegion();
return true;
}
/** /**
* Starts presentation of tasks in this container. * Starts presentation of tasks in this container.
*/ */
public abstract void start(); public void start() {
updateLocationAndTapExcludeRegion();
}
/** /**
* Stops presentation of tasks in this container. * Stops presentation of tasks in this container.
*/ */
public abstract void stop(); public void stop() {
clearTapExcludeRegion();
}
/** /**
* This should be called whenever the position or size of the surface changes * This should be called whenever the position or size of the surface changes
* or if touchable areas above the surface are added or removed. * or if touchable areas above the surface are added or removed.
*/ */
public abstract void notifyBoundsChanged(); public void notifyBoundsChanged() {
updateLocationAndTapExcludeRegion();
}
/** /**
* Called to update the dimensions whenever the host size changes. * Called to update the dimensions whenever the host size changes.
@@ -267,6 +284,48 @@ public abstract class TaskEmbedder {
// Do nothing // Do nothing
} }
/**
* Updates position and bounds information needed by WM and IME to manage window
* focus and touch events properly.
* <p>
* This should be called whenever the position or size of the surface changes
* or if touchable areas above the surface are added or removed.
*/
protected void updateLocationAndTapExcludeRegion() {
if (!isInitialized() || mHost.getWindow() == null) {
return;
}
applyTapExcludeRegion(mHost.getWindow(), mHost.getTapExcludeRegion());
}
/**
* Call to update the tap exclude region for the window.
* <p>
* This should not normally be called directly, but through
* {@link #updateLocationAndTapExcludeRegion()}. This method
* is provided as an optimization when managing multiple TaskSurfaces within a view.
*
* @see IWindowSession#updateTapExcludeRegion(IWindow, Region)
*/
private void applyTapExcludeRegion(IWindow window, @Nullable Region tapExcludeRegion) {
try {
IWindowSession session = WindowManagerGlobal.getWindowSession();
session.updateTapExcludeRegion(window, tapExcludeRegion);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
}
/**
* Removes the tap exclude region set by {@link #updateLocationAndTapExcludeRegion()}.
*/
private void clearTapExcludeRegion() {
if (!isInitialized() || mHost.getWindow() == null) {
return;
}
applyTapExcludeRegion(mHost.getWindow(), null);
}
/** /**
* Set the callback to be notified about state changes. * Set the callback to be notified about state changes.
* <p>This class must finish initializing before {@link #startActivity(Intent)} can be called. * <p>This class must finish initializing before {@link #startActivity(Intent)} can be called.

View File

@@ -75,7 +75,8 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
// infrastructure is ready. // infrastructure is ready.
mTaskOrganizer.registerOrganizer(WINDOWING_MODE_MULTI_WINDOW); mTaskOrganizer.registerOrganizer(WINDOWING_MODE_MULTI_WINDOW);
mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true); mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true);
return true;
return super.onInitialize();
} }
@Override @Override
@@ -96,6 +97,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
*/ */
@Override @Override
public void start() { public void start() {
super.start();
if (DEBUG) { if (DEBUG) {
log("start"); log("start");
} }
@@ -119,6 +121,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
*/ */
@Override @Override
public void stop() { public void stop() {
super.stop();
if (DEBUG) { if (DEBUG) {
log("stop"); log("stop");
} }
@@ -143,6 +146,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
*/ */
@Override @Override
public void notifyBoundsChanged() { public void notifyBoundsChanged() {
super.notifyBoundsChanged();
if (DEBUG) { if (DEBUG) {
log("notifyBoundsChanged: screenBounds=" + mHost.getScreenBounds()); log("notifyBoundsChanged: screenBounds=" + mHost.getScreenBounds());
} }

View File

@@ -21,7 +21,6 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_C
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.INVALID_DISPLAY;
import android.annotation.Nullable;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.app.ActivityTaskManager; import android.app.ActivityTaskManager;
@@ -40,7 +39,6 @@ import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.view.IWindow;
import android.view.IWindowManager; import android.view.IWindowManager;
import android.view.IWindowSession; import android.view.IWindowSession;
import android.view.InputDevice; import android.view.InputDevice;
@@ -134,20 +132,15 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
e.rethrowAsRuntimeException(); e.rethrowAsRuntimeException();
} }
if (mHost.getWindow() != null) { return super.onInitialize();
updateLocationAndTapExcludeRegion();
}
return true;
} }
@Override @Override
protected boolean onRelease() { protected boolean onRelease() {
super.onRelease();
// Clear activity view geometry for IME on this display // Clear activity view geometry for IME on this display
clearActivityViewGeometryForIme(); clearActivityViewGeometryForIme();
// Clear tap-exclude region (if any) for this window.
clearTapExcludeRegion();
if (mTaskStackListener != null) { if (mTaskStackListener != null) {
try { try {
mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener); mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
@@ -170,9 +163,9 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
*/ */
@Override @Override
public void start() { public void start() {
super.start();
if (isInitialized()) { if (isInitialized()) {
mVirtualDisplay.setDisplayState(true); mVirtualDisplay.setDisplayState(true);
updateLocationAndTapExcludeRegion();
} }
} }
@@ -181,22 +174,13 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
*/ */
@Override @Override
public void stop() { public void stop() {
super.stop();
if (isInitialized()) { if (isInitialized()) {
mVirtualDisplay.setDisplayState(false); mVirtualDisplay.setDisplayState(false);
clearActivityViewGeometryForIme(); clearActivityViewGeometryForIme();
clearTapExcludeRegion();
} }
} }
/**
* This should be called whenever the position or size of the surface changes
* or if touchable areas above the surface are added or removed.
*/
@Override
public void notifyBoundsChanged() {
updateLocationAndTapExcludeRegion();
}
/** /**
* Called to update the dimensions whenever the host size changes. * Called to update the dimensions whenever the host size changes.
* *
@@ -298,12 +282,13 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
* This should be called whenever the position or size of the surface changes * This should be called whenever the position or size of the surface changes
* or if touchable areas above the surface are added or removed. * or if touchable areas above the surface are added or removed.
*/ */
private void updateLocationAndTapExcludeRegion() { @Override
protected void updateLocationAndTapExcludeRegion() {
super.updateLocationAndTapExcludeRegion();
if (!isInitialized() || mHost.getWindow() == null) { if (!isInitialized() || mHost.getWindow() == null) {
return; return;
} }
reportLocation(mHost.getScreenToTaskMatrix(), mHost.getPositionInWindow()); reportLocation(mHost.getScreenToTaskMatrix(), mHost.getPositionInWindow());
applyTapExcludeRegion(mHost.getWindow(), mHost.getTapExcludeRegion());
} }
/** /**
@@ -331,24 +316,6 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
} }
} }
/**
* Call to update the tap exclude region for the window.
* <p>
* This should not normally be called directly, but through
* {@link #updateLocationAndTapExcludeRegion()}. This method
* is provided as an optimization when managing multiple TaskSurfaces within a view.
*
* @see IWindowSession#updateTapExcludeRegion(IWindow, Region)
*/
private void applyTapExcludeRegion(IWindow window, @Nullable Region tapExcludeRegion) {
try {
IWindowSession session = WindowManagerGlobal.getWindowSession();
session.updateTapExcludeRegion(window, tapExcludeRegion);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
}
/** /**
* @see InputMethodManager#reportActivityView(int, Matrix) * @see InputMethodManager#reportActivityView(int, Matrix)
*/ */
@@ -357,17 +324,6 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
mContext.getSystemService(InputMethodManager.class).reportActivityView(displayId, null); mContext.getSystemService(InputMethodManager.class).reportActivityView(displayId, null);
} }
/**
* Removes the tap exclude region set by {@link #updateLocationAndTapExcludeRegion()}.
*/
private void clearTapExcludeRegion() {
if (mHost.getWindow() == null) {
Log.w(TAG, "clearTapExcludeRegion: not attached to window!");
return;
}
applyTapExcludeRegion(mHost.getWindow(), null);
}
private static KeyEvent createKeyEvent(int action, int code, int displayId) { private static KeyEvent createKeyEvent(int action, int code, int displayId) {
long when = SystemClock.uptimeMillis(); long when = SystemClock.uptimeMillis();
final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */, final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,