Merge "Do not allow multiple started OnBackPressCallbacks" into androidx-main
diff --git a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
index b0fefbf..a02a5eb 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
@@ -448,4 +448,58 @@
assertThat(unregisterCount).isEqualTo(1)
}
+
+ @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Test
+ fun testDoubleStartCallbackCausesCancel() {
+ var registerCount = 0
+ var unregisterCount = 0
+ val invoker = object : OnBackInvokedDispatcher {
+ override fun registerOnBackInvokedCallback(p0: Int, p1: OnBackInvokedCallback) {
+ registerCount++
+ }
+
+ override fun unregisterOnBackInvokedCallback(p0: OnBackInvokedCallback) {
+ unregisterCount++
+ }
+ }
+
+ val dispatcher = OnBackPressedDispatcher()
+
+ dispatcher.setOnBackInvokedDispatcher(invoker)
+
+ var cancelledCount = 0
+ val callback1 = object : OnBackPressedCallback(true) {
+ override fun handleOnBackStarted(backEvent: BackEventCompat) { }
+ override fun handleOnBackProgressed(backEvent: BackEventCompat) {}
+ override fun handleOnBackPressed() { }
+ override fun handleOnBackCancelled() {
+ cancelledCount++
+ }
+ }
+
+ dispatcher.addCallback(callback1)
+
+ assertThat(registerCount).isEqualTo(1)
+
+ dispatcher.dispatchOnBackStarted(BackEventCompat(0.1F, 0.1F, 0.1F, EDGE_LEFT))
+
+ val callback2 = object : OnBackPressedCallback(true) {
+ override fun handleOnBackStarted(backEvent: BackEventCompat) { }
+ override fun handleOnBackProgressed(backEvent: BackEventCompat) {}
+ override fun handleOnBackPressed() { }
+ override fun handleOnBackCancelled() { }
+ }
+
+ dispatcher.addCallback(callback2)
+
+ assertThat(registerCount).isEqualTo(2)
+
+ dispatcher.dispatchOnBackStarted(BackEventCompat(0.1F, 0.1F, 0.1F, EDGE_LEFT))
+
+ assertThat(cancelledCount).isEqualTo(1)
+
+ assertThat(unregisterCount).isEqualTo(1)
+ }
}
diff --git a/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.kt b/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.kt
index 04d0388..094d95e 100644
--- a/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.kt
+++ b/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.kt
@@ -233,6 +233,9 @@
val callback = onBackPressedCallbacks.lastOrNull {
it.isEnabled
}
+ if (inProgressCallback != null) {
+ onBackCancelled()
+ }
inProgressCallback = callback
if (callback != null) {
callback.handleOnBackStarted(backEvent)