diff --git a/sky/services/common/BUILD.gn b/sky/services/common/BUILD.gn index a36c72e2bfb60..d16e78f10ac9f 100644 --- a/sky/services/common/BUILD.gn +++ b/sky/services/common/BUILD.gn @@ -4,6 +4,7 @@ if (is_android) { android_library("common_lib") { java_files = [ + "src/org/domokit/common/ActivityLifecycleListener.java", "src/org/domokit/common/ResourcePaths.java", ] } diff --git a/sky/services/platform/BUILD.gn b/sky/services/platform/BUILD.gn index da7e4b42b86f0..e1ec7b1f0e406 100644 --- a/sky/services/platform/BUILD.gn +++ b/sky/services/platform/BUILD.gn @@ -32,6 +32,7 @@ if (is_android) { "//base:base_java", "//mojo/public/java:bindings", "//mojo/public/java:system", + "//sky/services/common:common_lib", ":interfaces_java", ] } diff --git a/sky/services/platform/src/org/domokit/platform/SystemChromeImpl.java b/sky/services/platform/src/org/domokit/platform/SystemChromeImpl.java index 53909c2fc7329..c9e7695a8174c 100644 --- a/sky/services/platform/src/org/domokit/platform/SystemChromeImpl.java +++ b/sky/services/platform/src/org/domokit/platform/SystemChromeImpl.java @@ -15,14 +15,18 @@ import org.chromium.mojom.flutter.platform.SystemChrome; import org.chromium.mojom.flutter.platform.SystemUiOverlay; +import org.domokit.common.ActivityLifecycleListener; + /** * Android implementation of SystemChrome. */ -public class SystemChromeImpl implements SystemChrome { +public class SystemChromeImpl implements SystemChrome, ActivityLifecycleListener { private final Activity mActivity; + private int mEnabledOverlays; public SystemChromeImpl(Activity activity) { mActivity = activity; + mEnabledOverlays = SystemUiOverlay.TOP | SystemUiOverlay.BOTTOM; } @Override @@ -84,19 +88,27 @@ public void setApplicationSwitcherDescription( @Override public void setEnabledSystemUiOverlays(int overlays, SetEnabledSystemUiOverlaysResponse callback) { + mEnabledOverlays = overlays; + updateSystemUiOverlays(); + callback.call(true); + } + + private void updateSystemUiOverlays() { int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; - if ((overlays & SystemUiOverlay.TOP) == 0) { + if ((mEnabledOverlays & SystemUiOverlay.TOP) == 0) { flags |= View.SYSTEM_UI_FLAG_FULLSCREEN; } - if ((overlays & SystemUiOverlay.BOTTOM) == 0) { + if ((mEnabledOverlays & SystemUiOverlay.BOTTOM) == 0) { flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; } + if (mEnabledOverlays == 0) { + flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + } mActivity.getWindow().getDecorView().setSystemUiVisibility(flags); - callback.call(true); } @Override @@ -106,4 +118,9 @@ public void setSystemUiOverlayStyle(int style, SetSystemUiOverlayStyleResponse c // so LIGHT vs DARK effectively isn't supported in Android. callback.call(true); } + + @Override + public void onPostResume() { + updateSystemUiOverlays(); + } } diff --git a/sky/shell/platform/android/io/flutter/view/FlutterMain.java b/sky/shell/platform/android/io/flutter/view/FlutterMain.java index a4767833edb77..23c6eaf799d07 100644 --- a/sky/shell/platform/android/io/flutter/view/FlutterMain.java +++ b/sky/shell/platform/android/io/flutter/view/FlutterMain.java @@ -149,78 +149,80 @@ private static void onServiceRegistryAvailable(final Context applicationContext, registry.register(Activity.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { return Activity.MANAGER.bind(new ActivityImpl(), pipe); } }); registry.register(Clipboard.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return Clipboard.MANAGER.bind(new ClipboardImpl(context), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + return Clipboard.MANAGER.bind(new ClipboardImpl(view.getContext()), pipe); } }); registry.register(MediaService.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return MediaService.MANAGER.bind(new MediaServiceImpl(context, core), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + return MediaService.MANAGER.bind(new MediaServiceImpl(view.getContext(), core), pipe); } }); registry.register(NetworkService.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return NetworkService.MANAGER.bind(new NetworkServiceImpl(context, core), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + return NetworkService.MANAGER.bind(new NetworkServiceImpl(view.getContext(), core), pipe); } }); registry.register(SensorService.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return SensorService.MANAGER.bind(new SensorServiceImpl(context), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + return SensorService.MANAGER.bind(new SensorServiceImpl(view.getContext()), pipe); } }); registry.register(VSyncProvider.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { return VSyncProvider.MANAGER.bind(new VSyncProviderImpl(pipe), pipe); } }); registry.register(HapticFeedback.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return HapticFeedback.MANAGER.bind(new HapticFeedbackImpl((android.app.Activity) context), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + return HapticFeedback.MANAGER.bind(new HapticFeedbackImpl((android.app.Activity) view.getContext()), pipe); } }); registry.register(PathProvider.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return PathProvider.MANAGER.bind(new PathProviderImpl(context), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + return PathProvider.MANAGER.bind(new PathProviderImpl(view.getContext()), pipe); } }); registry.register(SystemChrome.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return SystemChrome.MANAGER.bind(new SystemChromeImpl((android.app.Activity) context), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + SystemChromeImpl chrome = new SystemChromeImpl((android.app.Activity) view.getContext()); + view.addActivityLifecycleListener(chrome); + return SystemChrome.MANAGER.bind(chrome, pipe); } }); registry.register(SystemSound.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return SystemSound.MANAGER.bind(new SystemSoundImpl((android.app.Activity) context), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + return SystemSound.MANAGER.bind(new SystemSoundImpl((android.app.Activity) view.getContext()), pipe); } }); registry.register(UrlLauncher.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return UrlLauncher.MANAGER.bind(new UrlLauncherImpl((android.app.Activity) context), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + return UrlLauncher.MANAGER.bind(new UrlLauncherImpl((android.app.Activity) view.getContext()), pipe); } }); } @@ -262,11 +264,11 @@ private static void parseServicesConfig(Context applicationContext, ServiceRegis private static void registerService(ServiceRegistry registry, final String serviceName, final String className) { registry.register(serviceName, new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { try { return (Binding) Class.forName(className) - .getMethod("connectToService", Context.class, Core.class, MessagePipeHandle.class) - .invoke(null, context, core, pipe); + .getMethod("connectToService", FlutterView.class, Core.class, MessagePipeHandle.class) + .invoke(null, view, core, pipe); } catch(Exception e) { Log.e(TAG, "Failed to register service '" + serviceName + "'", e); throw new RuntimeException(e); diff --git a/sky/shell/platform/android/io/flutter/view/FlutterView.java b/sky/shell/platform/android/io/flutter/view/FlutterView.java index 9bd064f8a1ebf..97331c988b5e7 100644 --- a/sky/shell/platform/android/io/flutter/view/FlutterView.java +++ b/sky/shell/platform/android/io/flutter/view/FlutterView.java @@ -59,6 +59,7 @@ import java.util.Locale; import java.util.Map; +import org.domokit.common.ActivityLifecycleListener; import org.domokit.activity.ActivityImpl; import org.domokit.editing.KeyboardImpl; import org.domokit.editing.KeyboardViewState; @@ -92,6 +93,7 @@ public class FlutterView extends SurfaceView private final RawKeyboardServiceState mRawKeyboardState; private final AccessibilityManager mAccessibilityManager; private BroadcastReceiver discoveryReceiver; + private List mActivityLifecycleListeners; public FlutterView(Context context) { this(context, null); @@ -136,16 +138,17 @@ public void surfaceDestroyed(SurfaceHolder holder) { Core core = CoreImpl.getInstance(); - mPlatformServiceProvider = new ServiceProviderImpl(core, getContext(), ServiceRegistry.SHARED); + mPlatformServiceProvider = new ServiceProviderImpl(core, this, ServiceRegistry.SHARED); ServiceRegistry localRegistry = new ServiceRegistry(); configureLocalServices(localRegistry); - mViewServiceProvider = new ServiceProviderImpl(core, getContext(), localRegistry); + mViewServiceProvider = new ServiceProviderImpl(core, this, localRegistry); mAccessibilityManager = (AccessibilityManager)getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); mOnMessageListeners = new HashMap(); mAsyncOnMessageListeners = new HashMap(); + mActivityLifecycleListeners = new ArrayList(); setLocale(getResources().getConfiguration().locale); @@ -173,11 +176,18 @@ SkyEngine getEngine() { return mSkyEngine; } + public void addActivityLifecycleListener(ActivityLifecycleListener listener) { + mActivityLifecycleListeners.add(listener); + } + public void onPause() { mSkyEngine.onAppLifecycleStateChanged(AppLifecycleState.PAUSED); } public void onPostResume() { + for (ActivityLifecycleListener listener : mActivityLifecycleListeners) + listener.onPostResume(); + mSkyEngine.onAppLifecycleStateChanged(AppLifecycleState.RESUMED); } @@ -369,21 +379,21 @@ public final WindowInsets onApplyWindowInsets(WindowInsets insets) { private void configureLocalServices(ServiceRegistry registry) { registry.register(Keyboard.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { - return Keyboard.MANAGER.bind(new KeyboardImpl(context, mKeyboardState), pipe); + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { + return Keyboard.MANAGER.bind(new KeyboardImpl(view.getContext(), mKeyboardState), pipe); } }); registry.register(RawKeyboardService.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { return RawKeyboardService.MANAGER.bind(new RawKeyboardServiceImpl(mRawKeyboardState), pipe); } }); registry.register(ApplicationMessages.MANAGER.getName(), new ServiceFactory() { @Override - public Binding connectToService(Context context, Core core, MessagePipeHandle pipe) { + public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { return ApplicationMessages.MANAGER.bind(new ApplicationMessagesImpl(), pipe); } }); diff --git a/sky/shell/platform/android/io/flutter/view/ServiceFactory.java b/sky/shell/platform/android/io/flutter/view/ServiceFactory.java index 25b882601c90b..684775e07d3cb 100644 --- a/sky/shell/platform/android/io/flutter/view/ServiceFactory.java +++ b/sky/shell/platform/android/io/flutter/view/ServiceFactory.java @@ -16,5 +16,5 @@ * clients. **/ interface ServiceFactory { - Binding connectToService(Context context, Core core, MessagePipeHandle pipe); + Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe); } diff --git a/sky/shell/platform/android/io/flutter/view/ServiceProviderImpl.java b/sky/shell/platform/android/io/flutter/view/ServiceProviderImpl.java index b39cbdd741526..3497306be3f6f 100644 --- a/sky/shell/platform/android/io/flutter/view/ServiceProviderImpl.java +++ b/sky/shell/platform/android/io/flutter/view/ServiceProviderImpl.java @@ -23,15 +23,15 @@ class ServiceProviderImpl implements ServiceProvider { private static final String TAG = "ServiceProviderImpl"; private Core mCore; - private Context mContext; + private FlutterView mView; private ServiceRegistry mRegistry; private HashSet mBindings = new HashSet(); - ServiceProviderImpl(Core core, Context context, ServiceRegistry registry) { + ServiceProviderImpl(Core core, FlutterView view, ServiceRegistry registry) { assert core != null; - assert context != null; + assert view != null; mCore = core; - mContext = context; + mView = view; mRegistry = registry; } @@ -48,7 +48,7 @@ public void connectToService(String interfaceName, MessagePipeHandle pipe) { pipe.close(); return; } - final Binding binding = factory.connectToService(mContext, mCore, pipe); + final Binding binding = factory.connectToService(mView, mCore, pipe); mBindings.add(binding); binding.registerErrorHandler(new ConnectionErrorHandler() { @Override