• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package io.flutter.embedding.engine.plugins.shim;
6 
7 import android.app.Activity;
8 import android.content.Context;
9 import android.support.annotation.NonNull;
10 
11 import java.util.HashSet;
12 import java.util.Map;
13 import java.util.Set;
14 
15 import io.flutter.Log;
16 import io.flutter.embedding.engine.plugins.FlutterPlugin;
17 import io.flutter.embedding.engine.plugins.activity.ActivityAware;
18 import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
19 import io.flutter.plugin.common.BinaryMessenger;
20 import io.flutter.plugin.common.PluginRegistry;
21 import io.flutter.plugin.platform.PlatformViewRegistry;
22 import io.flutter.view.FlutterMain;
23 import io.flutter.view.FlutterView;
24 import io.flutter.view.TextureRegistry;
25 
26 /**
27  * A {@link PluginRegistry.Registrar} that is shimmed to use the new Android embedding and plugin
28  * API behind the scenes.
29  * <p>
30  * Instances of {@code ShimRegistrar}s are vended internally by a {@link ShimPluginRegistry}.
31  */
32 class ShimRegistrar implements PluginRegistry.Registrar, FlutterPlugin, ActivityAware {
33   private static final String TAG = "ShimRegistrar";
34 
35   private final Map<String, Object> globalRegistrarMap;
36   private final String pluginId;
37   private final Set<PluginRegistry.ViewDestroyListener> viewDestroyListeners = new HashSet<>();
38   private final Set<PluginRegistry.RequestPermissionsResultListener> requestPermissionsResultListeners = new HashSet<>();
39   private final Set<PluginRegistry.ActivityResultListener> activityResultListeners = new HashSet<>();
40   private final Set<PluginRegistry.NewIntentListener> newIntentListeners = new HashSet<>();
41   private final Set<PluginRegistry.UserLeaveHintListener> userLeaveHintListeners = new HashSet<>();
42   private FlutterPlugin.FlutterPluginBinding pluginBinding;
43   private ActivityPluginBinding activityPluginBinding;
44 
ShimRegistrar(@onNull String pluginId, @NonNull Map<String, Object> globalRegistrarMap)45   public ShimRegistrar(@NonNull String pluginId, @NonNull Map<String, Object> globalRegistrarMap) {
46     this.pluginId = pluginId;
47     this.globalRegistrarMap = globalRegistrarMap;
48   }
49 
50   @Override
activity()51   public Activity activity() {
52     return activityPluginBinding != null ? activityPluginBinding.getActivity() : null;
53   }
54 
55   @Override
context()56   public Context context() {
57     return pluginBinding != null ? pluginBinding.getApplicationContext() : null;
58   }
59 
60   @Override
activeContext()61   public Context activeContext() {
62     return activityPluginBinding == null ? context() : activity();
63   }
64 
65   @Override
messenger()66   public BinaryMessenger messenger() {
67     return pluginBinding != null ? pluginBinding.getFlutterEngine().getDartExecutor() : null;
68   }
69 
70   @Override
textures()71   public TextureRegistry textures() {
72     return pluginBinding != null ? pluginBinding.getFlutterEngine().getRenderer() : null;
73   }
74 
75   @Override
platformViewRegistry()76   public PlatformViewRegistry platformViewRegistry() {
77     return pluginBinding != null ? pluginBinding.getFlutterEngine().getPlatformViewsController().getRegistry() : null;
78   }
79 
80   @Override
view()81   public FlutterView view() {
82     throw new UnsupportedOperationException("The new embedding does not support the old FlutterView.");
83   }
84 
85   @Override
lookupKeyForAsset(String asset)86   public String lookupKeyForAsset(String asset) {
87     return FlutterMain.getLookupKeyForAsset(asset);
88   }
89 
90   @Override
lookupKeyForAsset(String asset, String packageName)91   public String lookupKeyForAsset(String asset, String packageName) {
92     return FlutterMain.getLookupKeyForAsset(asset, packageName);
93   }
94 
95   @Override
publish(Object value)96   public PluginRegistry.Registrar publish(Object value) {
97     globalRegistrarMap.put(pluginId, value);
98     return this;
99   }
100 
101   @Override
addRequestPermissionsResultListener(PluginRegistry.RequestPermissionsResultListener listener)102   public PluginRegistry.Registrar addRequestPermissionsResultListener(PluginRegistry.RequestPermissionsResultListener listener) {
103     requestPermissionsResultListeners.add(listener);
104 
105     if (activityPluginBinding != null) {
106       activityPluginBinding.addRequestPermissionsResultListener(listener);
107     }
108 
109     return this;
110   }
111 
112   @Override
addActivityResultListener(PluginRegistry.ActivityResultListener listener)113   public PluginRegistry.Registrar addActivityResultListener(PluginRegistry.ActivityResultListener listener) {
114     activityResultListeners.add(listener);
115 
116     if (activityPluginBinding != null) {
117       activityPluginBinding.addActivityResultListener(listener);
118     }
119 
120     return this;
121   }
122 
123   @Override
addNewIntentListener(PluginRegistry.NewIntentListener listener)124   public PluginRegistry.Registrar addNewIntentListener(PluginRegistry.NewIntentListener listener) {
125     newIntentListeners.add(listener);
126 
127     if (activityPluginBinding != null) {
128       activityPluginBinding.addOnNewIntentListener(listener);
129     }
130 
131     return this;
132   }
133 
134   @Override
addUserLeaveHintListener(PluginRegistry.UserLeaveHintListener listener)135   public PluginRegistry.Registrar addUserLeaveHintListener(PluginRegistry.UserLeaveHintListener listener) {
136     userLeaveHintListeners.add(listener);
137 
138     if (activityPluginBinding != null) {
139       activityPluginBinding.addOnUserLeaveHintListener(listener);
140     }
141 
142     return this;
143   }
144 
145   @Override
146   @NonNull
addViewDestroyListener(@onNull PluginRegistry.ViewDestroyListener listener)147   public PluginRegistry.Registrar addViewDestroyListener(@NonNull PluginRegistry.ViewDestroyListener listener) {
148     viewDestroyListeners.add(listener);
149     return this;
150   }
151 
152   @Override
onAttachedToEngine(@onNull FlutterPluginBinding binding)153   public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
154     Log.v(TAG, "Attached to FlutterEngine.");
155     pluginBinding = binding;
156   }
157 
158   @Override
onDetachedFromEngine(@onNull FlutterPluginBinding binding)159   public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
160     Log.v(TAG, "Detached from FlutterEngine.");
161     for (PluginRegistry.ViewDestroyListener listener : viewDestroyListeners) {
162       // The following invocation might produce unexpected behavior in old plugins because
163       // we have no FlutterNativeView to pass to onViewDestroy(). This is a limitation of this shim.
164       listener.onViewDestroy(null);
165     }
166 
167     pluginBinding = null;
168   }
169 
170   @Override
onAttachedToActivity(@onNull ActivityPluginBinding binding)171   public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
172     Log.v(TAG, "Attached to an Activity.");
173     activityPluginBinding = binding;
174     addExistingListenersToActivityPluginBinding();
175   }
176 
177   @Override
onDetachedFromActivityForConfigChanges()178   public void onDetachedFromActivityForConfigChanges() {
179     Log.v(TAG, "Detached from an Activity for config changes.");
180     activityPluginBinding = null;
181   }
182 
183   @Override
onReattachedToActivityForConfigChanges(@onNull ActivityPluginBinding binding)184   public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
185     Log.v(TAG, "Reconnected to an Activity after config changes.");
186     activityPluginBinding = binding;
187     addExistingListenersToActivityPluginBinding();
188   }
189 
190   @Override
onDetachedFromActivity()191   public void onDetachedFromActivity() {
192     Log.v(TAG, "Detached from an Activity.");
193     activityPluginBinding = null;
194   }
195 
addExistingListenersToActivityPluginBinding()196   private void addExistingListenersToActivityPluginBinding() {
197     for (PluginRegistry.RequestPermissionsResultListener listener : requestPermissionsResultListeners) {
198       activityPluginBinding.addRequestPermissionsResultListener(listener);
199     }
200     for (PluginRegistry.ActivityResultListener listener : activityResultListeners) {
201       activityPluginBinding.addActivityResultListener(listener);
202     }
203     for (PluginRegistry.NewIntentListener listener : newIntentListeners) {
204       activityPluginBinding.addOnNewIntentListener(listener);
205     }
206     for (PluginRegistry.UserLeaveHintListener listener : userLeaveHintListeners) {
207       activityPluginBinding.addOnUserLeaveHintListener(listener);
208     }
209   }
210 }
211