From 15c6251ad70ea0e6bff5dce62b8e007a05bbe77e Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 22 Mar 2018 09:44:29 -0700 Subject: [PATCH 01/10] do not pause rendering when android view loses focus --- .../android/io/flutter/app/FlutterActivityDelegate.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java index 9de35c4b480a7..acbe15ef8da9d 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java @@ -201,9 +201,6 @@ public void onPause() { flutterApp.setCurrentActivity(null); } } - if (flutterView != null) { - flutterView.onPause(); - } } @Override From f0d8f0e7f8e93de709b740f33bfc00a1ee3329ed Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 22 Mar 2018 12:26:43 -0700 Subject: [PATCH 02/10] add onStop and onRestart hooks to flutter activity --- .../android/io/flutter/app/FlutterActivity.java | 12 ++++++++++++ .../io/flutter/app/FlutterActivityDelegate.java | 11 +++++++++++ .../io/flutter/app/FlutterActivityEvents.java | 4 ++++ .../io/flutter/app/FlutterFragmentActivity.java | 13 +++++++++++++ 4 files changed, 40 insertions(+) diff --git a/shell/platform/android/io/flutter/app/FlutterActivity.java b/shell/platform/android/io/flutter/app/FlutterActivity.java index f01e85a1a2437..dc40cfb786ad5 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivity.java +++ b/shell/platform/android/io/flutter/app/FlutterActivity.java @@ -100,6 +100,18 @@ public void onBackPressed() { } } + @Override + protected void onRestart() { + eventDelegate.onRestart(); + super.onRestart(); + } + + @Override + protected void onStop() { + eventDelegate.onStop(); + super.onStop(); + } + @Override protected void onPause() { super.onPause(); diff --git a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java index acbe15ef8da9d..4f09a1bf028db 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java @@ -215,6 +215,17 @@ public void onResume() { } } + @Override + public void onRestart() { + Log.i(TAG, "onRestart"); + } + + @Override + public void onStop() { + Log.i(TAG, "onStop"); + flutterView.onStop(); + } + @Override public void onPostResume() { if (flutterView != null) { diff --git a/shell/platform/android/io/flutter/app/FlutterActivityEvents.java b/shell/platform/android/io/flutter/app/FlutterActivityEvents.java index 98a3a1016c85f..daf6c0c8ac19e 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityEvents.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityEvents.java @@ -54,6 +54,10 @@ public interface FlutterActivityEvents */ void onDestroy(); + void onRestart(); + + void onStop(); + /** * Invoked when the activity has detected the user's press of the back key. * diff --git a/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java b/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java index cc8325df974e8..d70bf0be2c058 100644 --- a/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java +++ b/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java @@ -98,6 +98,19 @@ public void onBackPressed() { } } + @Override + protected void onRestart() { + eventDelegate.onRestart(); + super.onRestart(); + } + + @Override + protected void onStop() { + eventDelegate.onStop(); + super.onStop(); + } + + @Override protected void onPause() { super.onPause(); From 7369547422407471ada7250109097206b1f2787f Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 22 Mar 2018 12:43:20 -0700 Subject: [PATCH 03/10] add comments, null check, and remove engine special case --- shell/common/engine.cc | 3 +-- .../android/io/flutter/app/FlutterActivityDelegate.java | 7 ++++++- .../android/io/flutter/app/FlutterActivityEvents.java | 6 ++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 3629b729c29f7..7ec1d37e040fc 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -472,8 +472,7 @@ void Engine::DispatchPlatformMessage( bool Engine::HandleLifecyclePlatformMessage(blink::PlatformMessage* message) { const auto& data = message->data(); std::string state(reinterpret_cast(data.data()), data.size()); - if (state == "AppLifecycleState.paused" || - state == "AppLifecycleState.suspending") { + if (state == "AppLifecycleState.suspending") { activity_running_ = false; StopAnimator(); } else if (state == "AppLifecycleState.resumed" || diff --git a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java index 4f09a1bf028db..d60180f401123 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java @@ -201,6 +201,9 @@ public void onPause() { flutterApp.setCurrentActivity(null); } } + if (flutterView != null) { + flutterView.onPause(); + } } @Override @@ -223,7 +226,9 @@ public void onRestart() { @Override public void onStop() { Log.i(TAG, "onStop"); - flutterView.onStop(); + if (flutterView != null) { + flutterView.onStop(); + } } @Override diff --git a/shell/platform/android/io/flutter/app/FlutterActivityEvents.java b/shell/platform/android/io/flutter/app/FlutterActivityEvents.java index daf6c0c8ac19e..abba5b69a87e0 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityEvents.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityEvents.java @@ -54,8 +54,14 @@ public interface FlutterActivityEvents */ void onDestroy(); + /** + * @see android.app.Activity#onRestart() + */ void onRestart(); + /** + * @see android.app.Activity#onStop() + */ void onStop(); /** From 452778c10a75a15ac440a8ac7dbd75035b081528 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 23 Mar 2018 09:19:10 -0700 Subject: [PATCH 04/10] remove assert which we cannot guarantee --- .../android/io/flutter/app/FlutterActivity.java | 8 +------- .../io/flutter/app/FlutterActivityDelegate.java | 15 ++------------- .../io/flutter/app/FlutterActivityEvents.java | 5 ----- .../io/flutter/app/FlutterFragmentActivity.java | 6 ------ .../io/flutter/view/FlutterNativeView.java | 9 ++++++++- 5 files changed, 11 insertions(+), 32 deletions(-) diff --git a/shell/platform/android/io/flutter/app/FlutterActivity.java b/shell/platform/android/io/flutter/app/FlutterActivity.java index dc40cfb786ad5..ab566c485a1e6 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivity.java +++ b/shell/platform/android/io/flutter/app/FlutterActivity.java @@ -99,13 +99,7 @@ public void onBackPressed() { super.onBackPressed(); } } - - @Override - protected void onRestart() { - eventDelegate.onRestart(); - super.onRestart(); - } - + @Override protected void onStop() { eventDelegate.onStop(); diff --git a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java index d60180f401123..7c99ef0debf64 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java @@ -201,9 +201,6 @@ public void onPause() { flutterApp.setCurrentActivity(null); } } - if (flutterView != null) { - flutterView.onPause(); - } } @Override @@ -217,18 +214,10 @@ public void onResume() { Log.i(TAG, "onResume app wasn't a FlutterApplication!!"); } } - - @Override - public void onRestart() { - Log.i(TAG, "onRestart"); - } - + @Override public void onStop() { - Log.i(TAG, "onStop"); - if (flutterView != null) { - flutterView.onStop(); - } + flutterView.onStop(); } @Override diff --git a/shell/platform/android/io/flutter/app/FlutterActivityEvents.java b/shell/platform/android/io/flutter/app/FlutterActivityEvents.java index abba5b69a87e0..8d8eb422aa338 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityEvents.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityEvents.java @@ -54,11 +54,6 @@ public interface FlutterActivityEvents */ void onDestroy(); - /** - * @see android.app.Activity#onRestart() - */ - void onRestart(); - /** * @see android.app.Activity#onStop() */ diff --git a/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java b/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java index d70bf0be2c058..92ecb2226a4e4 100644 --- a/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java +++ b/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java @@ -98,12 +98,6 @@ public void onBackPressed() { } } - @Override - protected void onRestart() { - eventDelegate.onRestart(); - super.onRestart(); - } - @Override protected void onStop() { eventDelegate.onStop(); diff --git a/shell/platform/android/io/flutter/view/FlutterNativeView.java b/shell/platform/android/io/flutter/view/FlutterNativeView.java index 034a86d09d91f..3cb74ff486eb7 100644 --- a/shell/platform/android/io/flutter/view/FlutterNativeView.java +++ b/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -128,7 +128,14 @@ private void attach(FlutterNativeView view) { // Called by native to send us a platform message. private void handlePlatformMessage(final String channel, byte[] message, final int replyId) { - assertAttached(); + // The platform may may not be attached immediately in certain cases where a bundle is run, + // since this runs on a separate thread. This mostly happens when the app restarts in dev + // mode when switching into split-screen mode. Preventing app restarts on layout and density + // changes will prevent this, and afterwards this can be changed back to an assert. + if (!isAttached()) { + Log.d(TAG, "PlatformView is not attached"); + return; + } BinaryMessageHandler handler = mMessageHandlers.get(channel); if (handler != null) { try { From a663b1b3b782f9966d8ed2c5f42eebff86dbba94 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 23 Mar 2018 09:21:50 -0700 Subject: [PATCH 05/10] remove missing onPause --- .../android/io/flutter/app/FlutterActivityDelegate.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java index 7c99ef0debf64..1c880d7e46987 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java @@ -201,6 +201,9 @@ public void onPause() { flutterApp.setCurrentActivity(null); } } + if (flutterView != null) { + flutterView.onPause(); + } } @Override @@ -214,7 +217,7 @@ public void onResume() { Log.i(TAG, "onResume app wasn't a FlutterApplication!!"); } } - + @Override public void onStop() { flutterView.onStop(); From b30ef9831484b0e82c49e61b32ace112130f375d Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 23 Mar 2018 09:29:45 -0700 Subject: [PATCH 06/10] use inactive lifecycle for android --- shell/platform/android/io/flutter/view/FlutterView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java index e875f00073831..81254252ad2b1 100644 --- a/shell/platform/android/io/flutter/view/FlutterView.java +++ b/shell/platform/android/io/flutter/view/FlutterView.java @@ -267,7 +267,7 @@ public void addActivityLifecycleListener(ActivityLifecycleListener listener) { } public void onPause() { - mFlutterLifecycleChannel.send("AppLifecycleState.paused"); + mFlutterLifecycleChannel.send("AppLifecycleState.inactive"); } public void onPostResume() { From 1c719bc6828c80aba7e88a13147f4297cb6a3289 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 23 Mar 2018 09:40:36 -0700 Subject: [PATCH 07/10] use paused instead of inactive for android --- shell/platform/android/io/flutter/view/FlutterView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java index 81254252ad2b1..4cf750e730f57 100644 --- a/shell/platform/android/io/flutter/view/FlutterView.java +++ b/shell/platform/android/io/flutter/view/FlutterView.java @@ -278,7 +278,7 @@ public void onPostResume() { } public void onStop() { - mFlutterLifecycleChannel.send("AppLifecycleState.suspending"); + mFlutterLifecycleChannel.send("AppLifecycleState.paused"); } public void onMemoryPressure() { From 7adbd70490fc2b66bd6f07a8fea4d40323369a66 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 23 Mar 2018 09:43:56 -0700 Subject: [PATCH 08/10] remove engine changes --- shell/common/engine.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 7ec1d37e040fc..3629b729c29f7 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -472,7 +472,8 @@ void Engine::DispatchPlatformMessage( bool Engine::HandleLifecyclePlatformMessage(blink::PlatformMessage* message) { const auto& data = message->data(); std::string state(reinterpret_cast(data.data()), data.size()); - if (state == "AppLifecycleState.suspending") { + if (state == "AppLifecycleState.paused" || + state == "AppLifecycleState.suspending") { activity_running_ = false; StopAnimator(); } else if (state == "AppLifecycleState.resumed" || From 84c121157599989f3939e47803bcad149ce61cc5 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 23 Mar 2018 09:50:03 -0700 Subject: [PATCH 09/10] fix typo --- shell/platform/android/io/flutter/view/FlutterNativeView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/android/io/flutter/view/FlutterNativeView.java b/shell/platform/android/io/flutter/view/FlutterNativeView.java index 3cb74ff486eb7..7b843878143f0 100644 --- a/shell/platform/android/io/flutter/view/FlutterNativeView.java +++ b/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -128,8 +128,8 @@ private void attach(FlutterNativeView view) { // Called by native to send us a platform message. private void handlePlatformMessage(final String channel, byte[] message, final int replyId) { - // The platform may may not be attached immediately in certain cases where a bundle is run, - // since this runs on a separate thread. This mostly happens when the app restarts in dev + // The platform may not be attached immediately in certain cases where a new bundle is run - + // the native view is created in a separate thread. This mostly happens when the app restarts in dev // mode when switching into split-screen mode. Preventing app restarts on layout and density // changes will prevent this, and afterwards this can be changed back to an assert. if (!isAttached()) { From e3019db889f78dfe49028125a1bfac6e124128e7 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 23 Mar 2018 09:56:18 -0700 Subject: [PATCH 10/10] update lifecycle doc --- lib/ui/window.dart | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 03f9009ab58fa..9f9d9cfc37313 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -47,10 +47,14 @@ enum AppLifecycleState { /// in the foreground inactive state. Apps transition to this state when in /// a phone call, responding to a TouchID request, when entering the app /// switcher or the control center, or when the UIViewController hosting the - /// Flutter app is transitioning. Apps in this state should assume that they - /// may be [paused] at any time. - /// - /// On Android, this state is currently unused. + /// Flutter app is transitioning. + /// + /// On Android, this corresponds to an app or the Flutter host view running + /// in the foreground inactive state. Apps transition to this state when + /// another activity is focused, such as a split-screen app, a phone call, + /// a picture-in-picture app, a system dialog, or another window. + /// + /// Apps in this state should assume that they may be [paused] at any time. inactive, /// The application is not currently visible to the user, not responding to