From 70a54c213994baa6da3ae4b2b7a62d29651585ef Mon Sep 17 00:00:00 2001 From: Justin McCandless Date: Wed, 31 Jul 2024 10:40:32 -0700 Subject: [PATCH] Revert "FlutterFragment predictive back (#52302)" This reverts commit c364b294c1f3df4e32ca15972bd06228b056fbb4. --- .../embedding/android/FlutterFragment.java | 25 ++----------------- .../android/FlutterFragmentActivity.java | 10 +++++--- .../android/FlutterFragmentTest.java | 21 +--------------- 3 files changed, 9 insertions(+), 47 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java index e26d13e80f74a..376142b9c7e55 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java @@ -1056,14 +1056,6 @@ public void onAttach(@NonNull Context context) { delegate.onAttach(context); if (getArguments().getBoolean(ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED, false)) { requireActivity().getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback); - // When Android handles a back gesture, it pops an Activity or goes back - // to the home screen. When Flutter handles a back gesture, it pops a - // route inside of the Flutter part of the app. By default, Android - // handles back gestures, so this callback is disabled. If, for example, - // the Flutter app has routes for which it wants to handle the back - // gesture, then it will enable this callback using - // setFrameworkHandlesBack. - onBackPressedCallback.setEnabled(false); } context.registerComponentCallbacks(this); } @@ -1671,14 +1663,9 @@ public boolean popSystemNavigator() { // Unless we disable the callback, the dispatcher call will trigger it. This will then // trigger the fragment's onBackPressed() implementation, which will call through to the // dart side and likely call back through to this method, creating an infinite call loop. - boolean enabledAtStart = onBackPressedCallback.isEnabled(); - if (enabledAtStart) { - onBackPressedCallback.setEnabled(false); - } + onBackPressedCallback.setEnabled(false); activity.getOnBackPressedDispatcher().onBackPressed(); - if (enabledAtStart) { - onBackPressedCallback.setEnabled(true); - } + onBackPressedCallback.setEnabled(true); return true; } } @@ -1686,14 +1673,6 @@ public boolean popSystemNavigator() { return false; } - @Override - public void setFrameworkHandlesBack(boolean frameworkHandlesBack) { - if (!getArguments().getBoolean(ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED, false)) { - return; - } - onBackPressedCallback.setEnabled(frameworkHandlesBack); - } - @VisibleForTesting @NonNull boolean shouldDelayFirstAndroidViewDraw() { diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java index fda8a7c21da97..65fb752f20816 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java @@ -518,7 +518,6 @@ protected FlutterFragment createFlutterFragment() { ? TransparencyMode.opaque : TransparencyMode.transparent; final boolean shouldDelayFirstAndroidViewDraw = renderMode == RenderMode.surface; - final boolean shouldAutomaticallyHandleOnBackPressed = true; if (getCachedEngineId() != null) { Log.v( @@ -543,7 +542,6 @@ protected FlutterFragment createFlutterFragment() { .shouldAttachEngineToActivity(shouldAttachEngineToActivity()) .destroyEngineWithFragment(shouldDestroyEngineWithHost()) .shouldDelayFirstAndroidViewDraw(shouldDelayFirstAndroidViewDraw) - .shouldAutomaticallyHandleOnBackPressed(shouldAutomaticallyHandleOnBackPressed) .build(); } else { Log.v( @@ -579,7 +577,6 @@ protected FlutterFragment createFlutterFragment() { .transparencyMode(transparencyMode) .shouldAttachEngineToActivity(shouldAttachEngineToActivity()) .shouldDelayFirstAndroidViewDraw(shouldDelayFirstAndroidViewDraw) - .shouldAutomaticallyHandleOnBackPressed(shouldAutomaticallyHandleOnBackPressed) .build(); } @@ -595,7 +592,6 @@ protected FlutterFragment createFlutterFragment() { .transparencyMode(transparencyMode) .shouldAttachEngineToActivity(shouldAttachEngineToActivity()) .shouldDelayFirstAndroidViewDraw(shouldDelayFirstAndroidViewDraw) - .shouldAutomaticallyHandleOnBackPressed(shouldAutomaticallyHandleOnBackPressed) .build(); } } @@ -620,6 +616,12 @@ protected void onNewIntent(@NonNull Intent intent) { super.onNewIntent(intent); } + @Override + @SuppressWarnings("MissingSuperCall") + public void onBackPressed() { + flutterFragment.onBackPressed(); + } + @Override public void onRequestPermissionsResult( int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java index 24d7c6ea32a5c..6cfc9e1c6009f 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java @@ -290,7 +290,7 @@ private FragmentActivity getMockFragmentActivity() { } @Test - public void itDelegatesOnBackPressedWithSetFrameworkHandlesBack() { + public void itDelegatesOnBackPressedAutomaticallyWhenEnabled() { // We need to mock FlutterJNI to avoid triggering native code. FlutterJNI flutterJNI = mock(FlutterJNI.class); when(flutterJNI.isAttached()).thenReturn(true); @@ -301,8 +301,6 @@ public void itDelegatesOnBackPressedWithSetFrameworkHandlesBack() { FlutterFragment fragment = FlutterFragment.withCachedEngine("my_cached_engine") - // This enables the use of onBackPressedCallback, which is what - // sends backs to the framework if setFrameworkHandlesBack is true. .shouldAutomaticallyHandleOnBackPressed(true) .build(); FragmentActivity activity = getMockFragmentActivity(); @@ -320,15 +318,8 @@ public void itDelegatesOnBackPressedWithSetFrameworkHandlesBack() { TestDelegateFactory delegateFactory = new TestDelegateFactory(mockDelegate); fragment.setDelegateFactory(delegateFactory); - // Calling onBackPressed now will still be handled by Android (the default), - // until setFrameworkHandlesBack is set to true. activity.getOnBackPressedDispatcher().onBackPressed(); - verify(mockDelegate, times(0)).onBackPressed(); - // Setting setFrameworkHandlesBack to true means the delegate will receive - // the back and Android won't handle it. - fragment.setFrameworkHandlesBack(true); - activity.getOnBackPressedDispatcher().onBackPressed(); verify(mockDelegate, times(1)).onBackPressed(); } @@ -370,20 +361,10 @@ public void handleOnBackPressed() { TestDelegateFactory delegateFactory = new TestDelegateFactory(mockDelegate); fragment.setDelegateFactory(delegateFactory); - assertTrue(callback.isEnabled()); - assertTrue(fragment.popSystemNavigator()); verify(mockDelegate, never()).onBackPressed(); assertTrue(onBackPressedCalled.get()); - assertTrue(callback.isEnabled()); - - callback.setEnabled(false); - assertFalse(callback.isEnabled()); - assertTrue(fragment.popSystemNavigator()); - - verify(mockDelegate, never()).onBackPressed(); - assertFalse(callback.isEnabled()); } @Test