49 implements PluginRegistry,
50 ActivityControlSurface,
51 ServiceControlSurface,
52 BroadcastReceiverControlSurface,
53 ContentProviderControlSurface {
54 private static final String TAG =
"FlutterEngineCxnRegstry";
58 private final Map<Class<? extends FlutterPlugin>, FlutterPlugin> plugins =
new HashMap<>();
62 @NonNull
private final FlutterPlugin.FlutterPluginBinding pluginBinding;
66 private final Map<Class<? extends FlutterPlugin>, ActivityAware> activityAwarePlugins =
69 @Nullable
private ExclusiveAppComponent<Activity> exclusiveActivity;
70 @Nullable
private FlutterEngineActivityPluginBinding activityPluginBinding;
71 private boolean isWaitingForActivityReattachment =
false;
75 private final Map<Class<? extends FlutterPlugin>, ServiceAware> serviceAwarePlugins =
78 @Nullable
private Service service;
79 @Nullable
private FlutterEngineServicePluginBinding servicePluginBinding;
83 private final Map<Class<? extends FlutterPlugin>, BroadcastReceiverAware>
84 broadcastReceiverAwarePlugins =
new HashMap<>();
86 @Nullable
private BroadcastReceiver broadcastReceiver;
87 @Nullable
private FlutterEngineBroadcastReceiverPluginBinding broadcastReceiverPluginBinding;
91 private final Map<Class<? extends FlutterPlugin>, ContentProviderAware>
92 contentProviderAwarePlugins =
new HashMap<>();
94 @Nullable
private ContentProvider contentProvider;
95 @Nullable
private FlutterEngineContentProviderPluginBinding contentProviderPluginBinding;
100 @NonNull FlutterLoader flutterLoader,
102 this.flutterEngine = flutterEngine;
104 new FlutterPlugin.FlutterPluginBinding(
107 flutterEngine.getDartExecutor(),
108 flutterEngine.getRenderer(),
109 flutterEngine.getPlatformViewsController().getRegistry(),
110 new DefaultFlutterAssets(flutterLoader),
120 detachFromAppComponent();
127 public void add(@NonNull FlutterPlugin plugin) {
128 try (TraceSection e =
130 "FlutterEngineConnectionRegistry#add " + plugin.getClass().getSimpleName())) {
131 if (
has(plugin.getClass())) {
134 "Attempted to register plugin ("
137 +
"already registered with this FlutterEngine ("
143 Log.
v(
TAG,
"Adding plugin: " + plugin);
146 plugins.put(plugin.getClass(), plugin);
147 plugin.onAttachedToEngine(pluginBinding);
152 if (plugin instanceof ActivityAware) {
153 ActivityAware activityAware = (ActivityAware) plugin;
154 activityAwarePlugins.put(plugin.getClass(), activityAware);
156 if (isAttachedToActivity()) {
157 activityAware.onAttachedToActivity(activityPluginBinding);
164 if (plugin instanceof ServiceAware) {
165 ServiceAware serviceAware = (ServiceAware) plugin;
166 serviceAwarePlugins.put(plugin.getClass(), serviceAware);
168 if (isAttachedToService()) {
169 serviceAware.onAttachedToService(servicePluginBinding);
176 if (plugin instanceof BroadcastReceiverAware) {
177 BroadcastReceiverAware broadcastReceiverAware = (BroadcastReceiverAware) plugin;
178 broadcastReceiverAwarePlugins.put(plugin.getClass(), broadcastReceiverAware);
180 if (isAttachedToBroadcastReceiver()) {
181 broadcastReceiverAware.onAttachedToBroadcastReceiver(broadcastReceiverPluginBinding);
188 if (plugin instanceof ContentProviderAware) {
189 ContentProviderAware contentProviderAware = (ContentProviderAware) plugin;
190 contentProviderAwarePlugins.put(plugin.getClass(), contentProviderAware);
192 if (isAttachedToContentProvider()) {
193 contentProviderAware.onAttachedToContentProvider(contentProviderPluginBinding);
200 public void add(@NonNull Set<FlutterPlugin> plugins) {
201 for (FlutterPlugin plugin : plugins) {
207 public boolean has(@NonNull Class<? extends FlutterPlugin> pluginClass) {
208 return plugins.containsKey(pluginClass);
212 public FlutterPlugin
get(@NonNull Class<? extends FlutterPlugin> pluginClass) {
213 return plugins.get(pluginClass);
217 public void remove(@NonNull Class<? extends FlutterPlugin> pluginClass) {
218 FlutterPlugin plugin = plugins.get(pluginClass);
219 if (plugin ==
null) {
223 try (TraceSection e =
225 "FlutterEngineConnectionRegistry#remove " + pluginClass.getSimpleName())) {
229 if (plugin instanceof ActivityAware) {
230 if (isAttachedToActivity()) {
231 ActivityAware activityAware = (ActivityAware) plugin;
232 activityAware.onDetachedFromActivity();
234 activityAwarePlugins.remove(pluginClass);
240 if (plugin instanceof ServiceAware) {
241 if (isAttachedToService()) {
242 ServiceAware serviceAware = (ServiceAware) plugin;
243 serviceAware.onDetachedFromService();
245 serviceAwarePlugins.remove(pluginClass);
251 if (plugin instanceof BroadcastReceiverAware) {
252 if (isAttachedToBroadcastReceiver()) {
253 BroadcastReceiverAware broadcastReceiverAware = (BroadcastReceiverAware) plugin;
254 broadcastReceiverAware.onDetachedFromBroadcastReceiver();
256 broadcastReceiverAwarePlugins.remove(pluginClass);
262 if (plugin instanceof ContentProviderAware) {
263 if (isAttachedToContentProvider()) {
264 ContentProviderAware contentProviderAware = (ContentProviderAware) plugin;
265 contentProviderAware.onDetachedFromContentProvider();
267 contentProviderAwarePlugins.remove(pluginClass);
272 plugin.onDetachedFromEngine(pluginBinding);
273 plugins.remove(pluginClass);
278 public void remove(@NonNull Set<Class<? extends FlutterPlugin>> pluginClasses) {
279 for (Class<? extends FlutterPlugin> pluginClass : pluginClasses) {
288 remove(
new HashSet<>(plugins.keySet()));
292 private void detachFromAppComponent() {
293 if (isAttachedToActivity()) {
295 }
else if (isAttachedToService()) {
297 }
else if (isAttachedToBroadcastReceiver()) {
299 }
else if (isAttachedToContentProvider()) {
305 private boolean isAttachedToActivity() {
306 return exclusiveActivity !=
null;
309 private Activity attachedActivity() {
310 return exclusiveActivity !=
null ? exclusiveActivity.getAppComponent() :
null;
315 @NonNull ExclusiveAppComponent<Activity> exclusiveActivity, @NonNull Lifecycle lifecycle) {
316 try (TraceSection e = TraceSection.scoped(
"FlutterEngineConnectionRegistry#attachToActivity")) {
317 if (this.exclusiveActivity !=
null) {
318 this.exclusiveActivity.detachFromFlutterEngine();
321 detachFromAppComponent();
322 this.exclusiveActivity = exclusiveActivity;
323 attachToActivityInternal(exclusiveActivity.getAppComponent(), lifecycle);
327 private void attachToActivityInternal(@NonNull Activity activity, @NonNull Lifecycle lifecycle) {
328 this.activityPluginBinding =
new FlutterEngineActivityPluginBinding(activity, lifecycle);
330 final boolean useSoftwareRendering =
331 activity.getIntent() !=
null
336 flutterEngine.getPlatformViewsController().setSoftwareRendering(useSoftwareRendering);
342 .getPlatformViewsController()
343 .attach(activity, flutterEngine.getRenderer(), flutterEngine.getDartExecutor());
346 for (ActivityAware activityAware : activityAwarePlugins.values()) {
347 if (isWaitingForActivityReattachment) {
348 activityAware.onReattachedToActivityForConfigChanges(activityPluginBinding);
350 activityAware.onAttachedToActivity(activityPluginBinding);
353 isWaitingForActivityReattachment =
false;
358 if (isAttachedToActivity()) {
359 try (TraceSection e =
361 "FlutterEngineConnectionRegistry#detachFromActivityForConfigChanges")) {
362 isWaitingForActivityReattachment =
true;
364 for (ActivityAware activityAware : activityAwarePlugins.values()) {
365 activityAware.onDetachedFromActivityForConfigChanges();
368 detachFromActivityInternal();
371 Log.
e(
TAG,
"Attempted to detach plugins from an Activity when no Activity was attached.");
377 if (isAttachedToActivity()) {
378 try (TraceSection e =
379 TraceSection.scoped(
"FlutterEngineConnectionRegistry#detachFromActivity")) {
380 for (ActivityAware activityAware : activityAwarePlugins.values()) {
381 activityAware.onDetachedFromActivity();
384 detachFromActivityInternal();
387 Log.
e(
TAG,
"Attempted to detach plugins from an Activity when no Activity was attached.");
391 private void detachFromActivityInternal() {
393 flutterEngine.getPlatformViewsController().detach();
395 exclusiveActivity =
null;
396 activityPluginBinding =
null;
401 int requestCode, @NonNull String[] permissions, @NonNull
int[] grantResult) {
402 if (isAttachedToActivity()) {
403 try (TraceSection e =
404 TraceSection.scoped(
"FlutterEngineConnectionRegistry#onRequestPermissionsResult")) {
405 return activityPluginBinding.onRequestPermissionsResult(
406 requestCode, permissions, grantResult);
411 "Attempted to notify ActivityAware plugins of onRequestPermissionsResult, but no Activity"
419 if (isAttachedToActivity()) {
420 try (TraceSection e =
421 TraceSection.scoped(
"FlutterEngineConnectionRegistry#onActivityResult")) {
422 return activityPluginBinding.onActivityResult(requestCode, resultCode, data);
427 "Attempted to notify ActivityAware plugins of onActivityResult, but no Activity was"
435 if (isAttachedToActivity()) {
436 try (TraceSection e = TraceSection.scoped(
"FlutterEngineConnectionRegistry#onNewIntent")) {
437 activityPluginBinding.onNewIntent(intent);
442 "Attempted to notify ActivityAware plugins of onNewIntent, but no Activity was"
449 if (isAttachedToActivity()) {
450 try (TraceSection e =
451 TraceSection.scoped(
"FlutterEngineConnectionRegistry#onUserLeaveHint")) {
452 activityPluginBinding.onUserLeaveHint();
457 "Attempted to notify ActivityAware plugins of onUserLeaveHint, but no Activity was"
464 if (isAttachedToActivity()) {
465 try (TraceSection e =
466 TraceSection.scoped(
"FlutterEngineConnectionRegistry#onSaveInstanceState")) {
467 activityPluginBinding.onSaveInstanceState(bundle);
472 "Attempted to notify ActivityAware plugins of onSaveInstanceState, but no Activity was"
479 if (isAttachedToActivity()) {
480 try (TraceSection e =
481 TraceSection.scoped(
"FlutterEngineConnectionRegistry#onRestoreInstanceState")) {
482 activityPluginBinding.onRestoreInstanceState(bundle);
487 "Attempted to notify ActivityAware plugins of onRestoreInstanceState, but no Activity was"
494 private boolean isAttachedToService() {
495 return service !=
null;
500 @NonNull Service service, @Nullable Lifecycle lifecycle,
boolean isForeground) {
501 try (TraceSection e = TraceSection.scoped(
"FlutterEngineConnectionRegistry#attachToService")) {
503 detachFromAppComponent();
505 this.service = service;
506 this.servicePluginBinding =
new FlutterEngineServicePluginBinding(service, lifecycle);
509 for (ServiceAware serviceAware : serviceAwarePlugins.values()) {
510 serviceAware.onAttachedToService(servicePluginBinding);
517 if (isAttachedToService()) {
518 try (TraceSection e =
519 TraceSection.scoped(
"FlutterEngineConnectionRegistry#detachFromService")) {
521 for (ServiceAware serviceAware : serviceAwarePlugins.values()) {
522 serviceAware.onDetachedFromService();
526 servicePluginBinding =
null;
529 Log.
e(
TAG,
"Attempted to detach plugins from a Service when no Service was attached.");
535 if (isAttachedToService()) {
536 try (TraceSection e =
537 TraceSection.scoped(
"FlutterEngineConnectionRegistry#onMoveToForeground")) {
538 servicePluginBinding.onMoveToForeground();
545 if (isAttachedToService()) {
546 try (TraceSection e =
547 TraceSection.scoped(
"FlutterEngineConnectionRegistry#onMoveToBackground")) {
548 servicePluginBinding.onMoveToBackground();
555 private boolean isAttachedToBroadcastReceiver() {
556 return broadcastReceiver !=
null;
561 @NonNull BroadcastReceiver broadcastReceiver, @NonNull Lifecycle lifecycle) {
562 try (TraceSection e =
563 TraceSection.scoped(
"FlutterEngineConnectionRegistry#attachToBroadcastReceiver")) {
565 detachFromAppComponent();
567 this.broadcastReceiver = broadcastReceiver;
568 this.broadcastReceiverPluginBinding =
569 new FlutterEngineBroadcastReceiverPluginBinding(broadcastReceiver);
575 for (BroadcastReceiverAware broadcastReceiverAware : broadcastReceiverAwarePlugins.values()) {
576 broadcastReceiverAware.onAttachedToBroadcastReceiver(broadcastReceiverPluginBinding);
583 if (isAttachedToBroadcastReceiver()) {
584 try (TraceSection e =
585 TraceSection.scoped(
"FlutterEngineConnectionRegistry#detachFromBroadcastReceiver")) {
588 for (BroadcastReceiverAware broadcastReceiverAware :
589 broadcastReceiverAwarePlugins.values()) {
590 broadcastReceiverAware.onDetachedFromBroadcastReceiver();
596 "Attempted to detach plugins from a BroadcastReceiver when no BroadcastReceiver was"
603 private boolean isAttachedToContentProvider() {
604 return contentProvider !=
null;
609 @NonNull ContentProvider contentProvider, @NonNull Lifecycle lifecycle) {
611 try (TraceSection e =
612 TraceSection.scoped(
"FlutterEngineConnectionRegistry#attachToContentProvider")) {
614 detachFromAppComponent();
616 this.contentProvider = contentProvider;
617 this.contentProviderPluginBinding =
618 new FlutterEngineContentProviderPluginBinding(contentProvider);
624 for (ContentProviderAware contentProviderAware : contentProviderAwarePlugins.values()) {
625 contentProviderAware.onAttachedToContentProvider(contentProviderPluginBinding);
632 if (isAttachedToContentProvider()) {
633 try (TraceSection e =
634 TraceSection.scoped(
"FlutterEngineConnectionRegistry#detachFromContentProvider")) {
637 for (ContentProviderAware contentProviderAware : contentProviderAwarePlugins.values()) {
638 contentProviderAware.onDetachedFromContentProvider();
644 "Attempted to detach plugins from a ContentProvider when no ContentProvider was"
650 private static class DefaultFlutterAssets
implements FlutterPlugin.FlutterAssets {
651 final FlutterLoader flutterLoader;
653 private DefaultFlutterAssets(@NonNull FlutterLoader flutterLoader) {
654 this.flutterLoader = flutterLoader;
657 public String getAssetFilePathByName(@NonNull String assetFileName) {
658 return flutterLoader.getLookupKeyForAsset(assetFileName);
661 public String getAssetFilePathByName(
662 @NonNull String assetFileName, @NonNull String packageName) {
663 return flutterLoader.getLookupKeyForAsset(assetFileName, packageName);
666 public String getAssetFilePathBySubpath(@NonNull String assetSubpath) {
667 return flutterLoader.getLookupKeyForAsset(assetSubpath);
670 public String getAssetFilePathBySubpath(
671 @NonNull String assetSubpath, @NonNull String packageName) {
672 return flutterLoader.getLookupKeyForAsset(assetSubpath, packageName);
676 private static class FlutterEngineActivityPluginBinding
implements ActivityPluginBinding {
677 @NonNull
private final Activity activity;
678 @NonNull
private final HiddenLifecycleReference hiddenLifecycleReference;
681 private final Set<io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener>
682 onRequestPermissionsResultListeners =
new HashSet<>();
685 private final Set<io.flutter.plugin.common.PluginRegistry.ActivityResultListener>
686 onActivityResultListeners =
new HashSet<>();
689 private final Set<io.flutter.plugin.common.PluginRegistry.NewIntentListener>
690 onNewIntentListeners =
new HashSet<>();
693 private final Set<io.flutter.plugin.common.PluginRegistry.UserLeaveHintListener>
694 onUserLeaveHintListeners =
new HashSet<>();
697 private final Set<io.flutter.plugin.common.PluginRegistry.WindowFocusChangedListener>
698 onWindowFocusChangedListeners =
new HashSet<>();
701 private final Set<OnSaveInstanceStateListener> onSaveInstanceStateListeners =
new HashSet<>();
703 public FlutterEngineActivityPluginBinding(
704 @NonNull Activity activity, @NonNull Lifecycle lifecycle) {
705 this.activity = activity;
706 this.hiddenLifecycleReference =
new HiddenLifecycleReference(lifecycle);
711 public Activity getActivity() {
717 public Object getLifecycle() {
718 return hiddenLifecycleReference;
722 public void addRequestPermissionsResultListener(
724 io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener listener) {
725 onRequestPermissionsResultListeners.add(listener);
729 public void removeRequestPermissionsResultListener(
731 io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener listener) {
732 onRequestPermissionsResultListeners.remove(listener);
740 boolean onRequestPermissionsResult(
741 int requestCode, @NonNull String[] permissions, @NonNull
int[] grantResult) {
742 boolean didConsumeResult =
false;
743 for (io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener listener :
744 onRequestPermissionsResultListeners) {
746 listener.onRequestPermissionsResult(requestCode, permissions, grantResult)
749 return didConsumeResult;
753 public void addActivityResultListener(
754 @NonNull io.flutter.plugin.common.PluginRegistry.ActivityResultListener listener) {
755 onActivityResultListeners.add(listener);
759 public void removeActivityResultListener(
760 @NonNull io.flutter.plugin.common.PluginRegistry.ActivityResultListener listener) {
761 onActivityResultListeners.remove(listener);
769 boolean onActivityResult(
int requestCode,
int resultCode, @Nullable Intent data) {
770 boolean didConsumeResult =
false;
771 for (io.flutter.plugin.common.PluginRegistry.ActivityResultListener listener :
772 new HashSet<>(onActivityResultListeners)) {
774 listener.onActivityResult(requestCode, resultCode, data) || didConsumeResult;
776 return didConsumeResult;
780 public void addOnNewIntentListener(
781 @NonNull io.flutter.plugin.common.PluginRegistry.NewIntentListener listener) {
782 onNewIntentListeners.add(listener);
786 public void removeOnNewIntentListener(
787 @NonNull io.flutter.plugin.common.PluginRegistry.NewIntentListener listener) {
788 onNewIntentListeners.remove(listener);
796 void onNewIntent(@Nullable Intent intent) {
797 for (io.flutter.plugin.common.PluginRegistry.NewIntentListener listener :
798 onNewIntentListeners) {
799 listener.onNewIntent(intent);
804 public void addOnUserLeaveHintListener(
805 @NonNull io.flutter.plugin.common.PluginRegistry.UserLeaveHintListener listener) {
806 onUserLeaveHintListeners.add(listener);
810 public void removeOnUserLeaveHintListener(
811 @NonNull io.flutter.plugin.common.PluginRegistry.UserLeaveHintListener listener) {
812 onUserLeaveHintListeners.remove(listener);
816 public void addOnWindowFocusChangedListener(
817 @NonNull io.flutter.plugin.common.PluginRegistry.WindowFocusChangedListener listener) {
818 onWindowFocusChangedListeners.add(listener);
822 public void removeOnWindowFocusChangedListener(
823 @NonNull io.flutter.plugin.common.PluginRegistry.WindowFocusChangedListener listener) {
824 onWindowFocusChangedListeners.remove(listener);
827 void onWindowFocusChanged(
boolean hasFocus) {
828 for (io.flutter.plugin.common.PluginRegistry.WindowFocusChangedListener listener :
829 onWindowFocusChangedListeners) {
830 listener.onWindowFocusChanged(hasFocus);
835 public void addOnSaveStateListener(@NonNull OnSaveInstanceStateListener listener) {
836 onSaveInstanceStateListeners.add(listener);
840 public void removeOnSaveStateListener(@NonNull OnSaveInstanceStateListener listener) {
841 onSaveInstanceStateListeners.remove(listener);
849 void onUserLeaveHint() {
850 for (io.flutter.plugin.common.PluginRegistry.UserLeaveHintListener listener :
851 onUserLeaveHintListeners) {
852 listener.onUserLeaveHint();
861 void onSaveInstanceState(@NonNull Bundle bundle) {
862 for (OnSaveInstanceStateListener listener : onSaveInstanceStateListeners) {
863 listener.onSaveInstanceState(bundle);
872 void onRestoreInstanceState(@Nullable Bundle bundle) {
873 for (OnSaveInstanceStateListener listener : onSaveInstanceStateListeners) {
874 listener.onRestoreInstanceState(bundle);
879 private static class FlutterEngineServicePluginBinding
implements ServicePluginBinding {
880 @NonNull
private final Service
service;
881 @Nullable
private final HiddenLifecycleReference hiddenLifecycleReference;
884 private final Set<ServiceAware.OnModeChangeListener> onModeChangeListeners =
new HashSet<>();
886 FlutterEngineServicePluginBinding(@NonNull Service service, @Nullable Lifecycle lifecycle) {
888 hiddenLifecycleReference = lifecycle !=
null ?
new HiddenLifecycleReference(lifecycle) : null;
893 public Service getService() {
899 public Object getLifecycle() {
900 return hiddenLifecycleReference;
904 public void addOnModeChangeListener(@NonNull ServiceAware.OnModeChangeListener listener) {
905 onModeChangeListeners.add(listener);
909 public void removeOnModeChangeListener(@NonNull ServiceAware.OnModeChangeListener listener) {
910 onModeChangeListeners.remove(listener);
913 void onMoveToForeground() {
914 for (ServiceAware.OnModeChangeListener listener : onModeChangeListeners) {
915 listener.onMoveToForeground();
919 void onMoveToBackground() {
920 for (ServiceAware.OnModeChangeListener listener : onModeChangeListeners) {
921 listener.onMoveToBackground();
926 private static class FlutterEngineBroadcastReceiverPluginBinding
927 implements BroadcastReceiverPluginBinding {
928 @NonNull
private final BroadcastReceiver broadcastReceiver;
930 FlutterEngineBroadcastReceiverPluginBinding(@NonNull BroadcastReceiver broadcastReceiver) {
931 this.broadcastReceiver = broadcastReceiver;
936 public BroadcastReceiver getBroadcastReceiver() {
937 return broadcastReceiver;
941 private static class FlutterEngineContentProviderPluginBinding
942 implements ContentProviderPluginBinding {
943 @NonNull
private final ContentProvider contentProvider;
945 FlutterEngineContentProviderPluginBinding(@NonNull ContentProvider contentProvider) {
946 this.contentProvider = contentProvider;
951 public ContentProvider getContentProvider() {
952 return contentProvider;