summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/ViewRootImpl.java2
-rw-r--r--core/java/android/window/OnBackInvokedDispatcher.java10
-rw-r--r--core/java/android/window/ProxyOnBackInvokedDispatcher.java2
-rw-r--r--core/java/android/window/WindowOnBackInvokedDispatcher.java1
-rw-r--r--data/etc/services.core.protolog.json6
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java77
7 files changed, 90 insertions, 16 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 931ae2748785..3b371faecacb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -10743,7 +10743,7 @@ public final class ViewRootImpl implements ViewParent,
private void registerBackCallbackOnWindow() {
if (OnBackInvokedDispatcher.DEBUG) {
Log.d(OnBackInvokedDispatcher.TAG, TextUtils.formatSimple(
- "ViewRootImpl.registerBackCallbackOnWindow. Callback:%s Package:%s "
+ "ViewRootImpl.registerBackCallbackOnWindow. Dispatcher:%s Package:%s "
+ "IWindow:%s Session:%s",
mOnBackInvokedDispatcher, mBasePackageName, mWindow, mWindowSession));
}
diff --git a/core/java/android/window/OnBackInvokedDispatcher.java b/core/java/android/window/OnBackInvokedDispatcher.java
index c254a9df3b4c..6bc2b5043e79 100644
--- a/core/java/android/window/OnBackInvokedDispatcher.java
+++ b/core/java/android/window/OnBackInvokedDispatcher.java
@@ -19,7 +19,6 @@ package android.window;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.os.Build;
@@ -93,15 +92,6 @@ public interface OnBackInvokedDispatcher {
void unregisterOnBackInvokedCallback(@NonNull OnBackInvokedCallback callback);
/**
- * Returns the most prioritized callback to receive back dispatch next.
- * @hide
- */
- @Nullable
- default OnBackInvokedCallback getTopCallback() {
- return null;
- }
-
- /**
* Registers a {@link OnBackInvokedCallback} with system priority.
* @hide
*/
diff --git a/core/java/android/window/ProxyOnBackInvokedDispatcher.java b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
index eb776310b8bb..8a3b4ac8ba8c 100644
--- a/core/java/android/window/ProxyOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
@@ -54,7 +54,7 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
public void registerOnBackInvokedCallback(
int priority, @NonNull OnBackInvokedCallback callback) {
if (DEBUG) {
- Log.v(TAG, String.format("Pending register %s. Actual=%s", callback,
+ Log.v(TAG, String.format("Proxy: register %s. actualDispatcherOwner=%s", callback,
mActualDispatcherOwner));
}
if (priority < 0) {
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 8811116b25ad..477da5e66651 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -175,7 +175,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
}
}
- @Override
public OnBackInvokedCallback getTopCallback() {
if (mAllCallbacks.isEmpty()) {
return null;
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 3a900e6e6bfa..80b144acd991 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -703,6 +703,12 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-1427392850": {
+ "message": "WindowState: Setting back callback %s (priority: %d) (Client IWindow: %s). (WindowState: %s)",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_BACK_PREVIEW",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
"-1427184084": {
"message": "addWindow: New client %s: window=%s Callers=%s",
"level": "VERBOSE",
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 88d17e4e6e0a..8546e8002602 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -250,6 +250,7 @@ import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.window.ClientWindowFrames;
import android.window.IOnBackInvokedCallback;
+import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.KeyInterceptionInfo;
@@ -1084,9 +1085,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
*/
void setOnBackInvokedCallback(
@Nullable IOnBackInvokedCallback onBackInvokedCallback, int priority) {
- ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "%s: Setting back callback %s. Client IWindow %s",
- this, onBackInvokedCallback, mClient);
- if (priority >= 0) {
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "WindowState: Setting back callback %s (priority: %d) "
+ + "(Client IWindow: %s). (WindowState: %s)",
+ onBackInvokedCallback, priority, mClient, this);
+ if (priority >= WindowOnBackInvokedDispatcher.PRIORITY_DEFAULT) {
mApplicationOnBackInvokedCallback = onBackInvokedCallback;
mSystemOnBackInvokedCallback = null;
} else {
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index f44de1e46c0f..a4a62a4254ad 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -23,8 +23,13 @@ import static android.window.BackNavigationInfo.typeToString;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertEquals;
+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.eq;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -32,13 +37,16 @@ import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.HardwareBuffer;
+import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.view.WindowManager;
import android.window.BackEvent;
import android.window.BackNavigationInfo;
import android.window.IOnBackInvokedCallback;
+import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
import android.window.TaskSnapshot;
+import android.window.WindowOnBackInvokedDispatcher;
import com.android.server.LocalServices;
@@ -46,6 +54,9 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
@Presubmit
@RunWith(WindowTestRunner.class)
public class BackNavigationControllerTests extends WindowTestsBase {
@@ -148,6 +159,61 @@ public class BackNavigationControllerTests extends WindowTestsBase {
assertThat(backNavigationInfo.getOnBackInvokedCallback()).isEqualTo(appCallback);
}
+ @Test
+ public void testUnregisterCallbacksWithSystemCallback()
+ throws InterruptedException, RemoteException {
+ CountDownLatch systemLatch = new CountDownLatch(1);
+ CountDownLatch appLatch = new CountDownLatch(1);
+
+ Task task = createTopTaskWithActivity();
+ WindowState appWindow = task.getTopVisibleAppMainWindow();
+ WindowOnBackInvokedDispatcher dispatcher = new WindowOnBackInvokedDispatcher();
+ doAnswer(invocation -> {
+ appWindow.setOnBackInvokedCallback(invocation.getArgument(1),
+ invocation.getArgument(2));
+ return null;
+ }).when(appWindow.mSession).setOnBackInvokedCallback(eq(appWindow.mClient), any(),
+ anyInt());
+
+ addToWindowMap(appWindow, true);
+ dispatcher.attachToWindow(appWindow.mSession, appWindow.mClient);
+
+
+ OnBackInvokedCallback appCallback = createBackCallback(appLatch);
+ OnBackInvokedCallback systemCallback = createBackCallback(systemLatch);
+
+ // Register both a system callback and an application callback
+ dispatcher.registerSystemOnBackInvokedCallback(systemCallback);
+ dispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+ appCallback);
+
+ // Check that the top callback is the app callback
+ assertEquals(appCallback, dispatcher.getTopCallback());
+
+ // Now unregister the app callback and check that the top callback is the system callback
+ dispatcher.unregisterOnBackInvokedCallback(appCallback);
+ assertEquals(systemCallback, dispatcher.getTopCallback());
+
+ // Verify that this has correctly been propagated to the server and that the
+ // BackNavigationInfo object will contain the system callback
+ BackNavigationInfo backNavigationInfo = startBackNavigation();
+ assertWithMessage("BackNavigationInfo").that(backNavigationInfo).isNotNull();
+ IOnBackInvokedCallback callback = backNavigationInfo.getOnBackInvokedCallback();
+ assertThat(callback).isNotNull();
+
+ try {
+ callback.onBackInvoked();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Check that the system callback has been call
+ assertTrue("System callback has not been called",
+ systemLatch.await(500, TimeUnit.MILLISECONDS));
+ assertEquals("App callback should not have been called",
+ 1, appLatch.getCount());
+ }
+
private IOnBackInvokedCallback withSystemCallback(Task task) {
IOnBackInvokedCallback callback = createOnBackInvokedCallback();
task.getTopMostActivity().getTopChild().setOnBackInvokedCallback(callback,
@@ -188,6 +254,17 @@ public class BackNavigationControllerTests extends WindowTestsBase {
};
}
+ private OnBackInvokedCallback createBackCallback(CountDownLatch latch) {
+ return new OnBackInvokedCallback() {
+ @Override
+ public void onBackInvoked() {
+ if (latch != null) {
+ latch.countDown();
+ }
+ }
+ };
+ }
+
@NonNull
private TaskSnapshotController createMockTaskSnapshotController() {
TaskSnapshotController taskSnapshotController = mock(TaskSnapshotController.class);