diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java index 3341db91c7569..f9eabc5015cd4 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java @@ -16,6 +16,7 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.util.TypedValue; @@ -66,7 +67,10 @@ * {@code Fragment}. */ // TODO(mattcarroll): explain each call forwarded to Fragment (first requires resolution of PluginRegistry API). -public class FlutterActivity extends FragmentActivity implements OnFirstFrameRenderedListener { +public class FlutterActivity extends FragmentActivity + implements FlutterFragment.FlutterEngineProvider, + FlutterFragment.FlutterEngineConfigurator, + OnFirstFrameRenderedListener { private static final String TAG = "FlutterActivity"; // Meta-data arguments, processed from manifest XML. @@ -365,6 +369,27 @@ protected boolean shouldAttachEngineToActivity() { return true; } + /** + * Hook for subclasses to easily provide a custom {@code FlutterEngine}. + */ + @Nullable + @Override + public FlutterEngine provideFlutterEngine(@NonNull Context context) { + // No-op. Hook for subclasses. + return null; + } + + /** + * Hook for subclasses to easily configure a {@code FlutterEngine}, e.g., register + * plugins. + *

+ * This method is called after {@link #provideFlutterEngine(Context)}. + */ + @Override + public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { + // No-op. Hook for subclasses. + } + @Override public void onPostResume() { super.onPostResume(); diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java index 59d9719dc940d..4893002a5f280 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java @@ -6,6 +6,8 @@ import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; +import android.app.Activity; +import android.arch.lifecycle.Lifecycle; import android.content.Context; import android.content.Intent; import android.os.Build; @@ -359,8 +361,13 @@ public void onAttach(@NonNull Context context) { // sync with the Activity. We use the Fragment's Lifecycle because it is possible that the // attached Activity is not a LifecycleOwner. Log.d(TAG, "Attaching FlutterEngine to the Activity that owns this Fragment."); - flutterEngine.getActivityControlSurface().attachToActivity(getActivity(), getLifecycle()); + flutterEngine.getActivityControlSurface().attachToActivity( + getActivity(), + getLifecycle() + ); } + + configureFlutterEngine(flutterEngine); } private void initializeFlutter(@NonNull Context context) { @@ -401,11 +408,11 @@ private void setupFlutterEngine() { // Defer to the Activity that owns us to provide a FlutterEngine. Log.d(TAG, "Deferring to attached Activity to provide a FlutterEngine."); FlutterEngineProvider flutterEngineProvider = (FlutterEngineProvider) attachedActivity; - flutterEngine = flutterEngineProvider.getFlutterEngine(getContext()); + flutterEngine = flutterEngineProvider.provideFlutterEngine(getContext()); if (flutterEngine != null) { isFlutterEngineFromActivity = true; + return; } - return; } // Neither our subclass, nor our owning Activity wanted to provide a custom FlutterEngine. @@ -434,11 +441,34 @@ protected FlutterEngine createFlutterEngine(@NonNull Context context) { return null; } + /** + * Configures a {@link FlutterEngine} after its creation. + *

+ * This method is called after the given {@link FlutterEngine} has been attached to the + * owning {@code FragmentActivity}. See + * {@link io.flutter.embedding.engine.plugins.activity.ActivityControlSurface#attachToActivity(Activity, Lifecycle)}. + *

+ * It is possible that the owning {@code FragmentActivity} opted not to connect itself as + * an {@link io.flutter.embedding.engine.plugins.activity.ActivityControlSurface}. In that + * case, any configuration, e.g., plugins, must not expect or depend upon an available + * {@code Activity} at the time that this method is invoked. + *

+ * The default behavior of this method is to defer to the owning {@code FragmentActivity} + * as a {@link FlutterEngineConfigurator}. Subclasses can override this method if the + * subclass needs to override the {@code FragmentActivity}'s behavior, or add to it. + */ + protected void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { + FragmentActivity attachedActivity = getActivity(); + if (attachedActivity instanceof FlutterEngineConfigurator) { + ((FlutterEngineConfigurator) attachedActivity).configureFlutterEngine(flutterEngine); + } + } + @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.v(TAG, "Creating FlutterView."); - flutterView = new FlutterView(getContext(), getRenderMode(), getTransparencyMode()); + flutterView = new FlutterView(getActivity(), getRenderMode(), getTransparencyMode()); flutterView.addOnFirstFrameRenderedListener(onFirstFrameRenderedListener); return flutterView; } @@ -548,10 +578,6 @@ public void run() { Log.v(TAG, "Attaching FlutterEngine to FlutterView."); flutterView.attachToFlutterEngine(flutterEngine); - // TODO(mattcarroll): the following call should exist here, but the plugin system needs to be revamped. - // The existing attach() method does not know how to handle this kind of FlutterView. - //flutterEngine.getPlugins().attach(this, getActivity()); - doInitialFlutterViewRun(); } }); @@ -788,7 +814,7 @@ protected void onFirstFrameRendered() {} * {@link FlutterActivity}s and/or {@code FlutterFragments}. *

* If the {@link FragmentActivity} that owns this {@code FlutterFragment} implements - * {@code FlutterEngineProvider}, that {@link FlutterActivity} will be given an opportunity + * {@code FlutterEngineProvider}, that {@link FragmentActivity} will be given an opportunity * to provide a {@link FlutterEngine} instead of the {@code FlutterFragment} creating a * new one. The {@link FragmentActivity} can provide an existing, pre-warmed {@link FlutterEngine}, * if desired. @@ -804,6 +830,27 @@ public interface FlutterEngineProvider { * to provide its own {@code FlutterEngine} instance. */ @Nullable - FlutterEngine getFlutterEngine(@NonNull Context context); + FlutterEngine provideFlutterEngine(@NonNull Context context); + } + + /** + * Configures a {@link FlutterEngine} after it is created, e.g., adds plugins. + *

+ * This interface may be applied to a {@link FragmentActivity} that owns a {@code FlutterFragment}. + */ + public interface FlutterEngineConfigurator { + /** + * Configures the given {@link FlutterEngine}. + *

+ * This method is called after the given {@link FlutterEngine} has been attached to the + * owning {@code FragmentActivity}. See + * {@link io.flutter.embedding.engine.plugins.activity.ActivityControlSurface#attachToActivity(Activity, Lifecycle)}. + *

+ * It is possible that the owning {@code FragmentActivity} opted not to connect itself as + * an {@link io.flutter.embedding.engine.plugins.activity.ActivityControlSurface}. In that + * case, any configuration, e.g., plugins, must not expect or depend upon an available + * {@code Activity} at the time that this method is invoked. + */ + void configureFlutterEngine(@NonNull FlutterEngine flutterEngine); } } diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterView.java b/shell/platform/android/io/flutter/embedding/android/FlutterView.java index 45ad7515effed..49b933c03ad44 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterView.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterView.java @@ -18,6 +18,7 @@ import android.util.AttributeSet; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.View; import android.view.WindowInsets; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeProvider; @@ -36,6 +37,7 @@ import io.flutter.embedding.engine.renderer.FlutterRenderer; import io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener; import io.flutter.plugin.editing.TextInputPlugin; +import io.flutter.plugin.platform.PlatformViewsController; import io.flutter.view.AccessibilityBridge; /** @@ -117,6 +119,8 @@ public void onFirstFrameRendered() { *

  • {@link #renderMode} defaults to {@link RenderMode#surface}.
  • *
  • {@link #transparencyMode} defaults to {@link TransparencyMode#opaque}.
  • * + * {@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} + * to be compatible with {@link PlatformViewsController}. */ public FlutterView(@NonNull Context context) { this(context, null, null, null); @@ -127,6 +131,9 @@ public FlutterView(@NonNull Context context) { * and allows selection of a {@link #renderMode}. *

    * {@link #transparencyMode} defaults to {@link TransparencyMode#opaque}. + *

    + * {@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} + * to be compatible with {@link PlatformViewsController}. */ public FlutterView(@NonNull Context context, @NonNull RenderMode renderMode) { this(context, null, renderMode, null); @@ -135,6 +142,9 @@ public FlutterView(@NonNull Context context, @NonNull RenderMode renderMode) { /** * Constructs a {@code FlutterView} programmatically, without any XML attributes, * assumes the use of {@link RenderMode#surface}, and allows selection of a {@link #transparencyMode}. + *

    + * {@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} + * to be compatible with {@link PlatformViewsController}. */ public FlutterView(@NonNull Context context, @NonNull TransparencyMode transparencyMode) { this(context, null, RenderMode.surface, transparencyMode); @@ -143,6 +153,9 @@ public FlutterView(@NonNull Context context, @NonNull TransparencyMode transpare /** * Constructs a {@code FlutterView} programmatically, without any XML attributes, and allows * a selection of {@link #renderMode} and {@link #transparencyMode}. + *

    + * {@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} + * to be compatible with {@link PlatformViewsController}. */ public FlutterView(@NonNull Context context, @NonNull RenderMode renderMode, @NonNull TransparencyMode transparencyMode) { this(context, null, renderMode, transparencyMode); @@ -150,9 +163,11 @@ public FlutterView(@NonNull Context context, @NonNull RenderMode renderMode, @No /** * Constructs a {@code FlutterSurfaceView} in an XML-inflation-compliant manner. - * - * // TODO(mattcarroll): expose renderMode in XML when build system supports R.attr + *

    + * {@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} + * to be compatible with {@link PlatformViewsController}. */ + // TODO(mattcarroll): expose renderMode in XML when build system supports R.attr public FlutterView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, null, null); } @@ -367,6 +382,21 @@ public InputConnection onCreateInputConnection(@NonNull EditorInfo outAttrs) { return textInputPlugin.createInputConnection(this, outAttrs); } + /** + * Allows a {@code View} that is not currently the input connection target to invoke commands on + * the {@link android.view.inputmethod.InputMethodManager}, which is otherwise disallowed. + *

    + * Returns true to allow non-input-connection-targets to invoke methods on + * {@code InputMethodManager}, or false to exclusively allow the input connection target to invoke + * such methods. + */ + @Override + public boolean checkInputConnectionProxy(View view) { + return flutterEngine != null + ? flutterEngine.getPlatformViewsController().checkInputConnectionProxy(view) + : super.checkInputConnectionProxy(view); + } + /** * Invoked when key is released. * @@ -511,7 +541,9 @@ private void resetWillNotDraw(boolean isAccessibilityEnabled, boolean isTouchExp * See {@link #detachFromFlutterEngine()} for information on how to detach from a * {@link FlutterEngine}. */ - public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) { + public void attachToFlutterEngine( + @NonNull FlutterEngine flutterEngine + ) { Log.d(TAG, "Attaching to a FlutterEngine: " + flutterEngine); if (isAttachedToFlutterEngine()) { if (flutterEngine == this.flutterEngine) { @@ -537,7 +569,7 @@ public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) { textInputPlugin = new TextInputPlugin( this, this.flutterEngine.getDartExecutor(), - null + this.flutterEngine.getPlatformViewsController() ); androidKeyProcessor = new AndroidKeyProcessor( this.flutterEngine.getKeyEventChannel(), @@ -549,9 +581,7 @@ public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) { flutterEngine.getAccessibilityChannel(), (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE), getContext().getContentResolver(), - // TODO(mattcaroll): plumb the platform views controller to the accessibility bridge. - // https://github.com/flutter/flutter/issues/29618 - null + this.flutterEngine.getPlatformViewsController() ); accessibilityBridge.setOnAccessibilityChangeListener(onAccessibilityChangeListener); resetWillNotDraw( @@ -559,6 +589,10 @@ public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) { accessibilityBridge.isTouchExplorationEnabled() ); + // Connect AccessibilityBridge to the PlatformViewsController within the FlutterEngine. + // This allows platform Views to hook into Flutter's overall accessibility system. + this.flutterEngine.getPlatformViewsController().attachAccessibilityBridge(accessibilityBridge); + // Inform the Android framework that it should retrieve a new InputConnection // now that an engine is attached. // TODO(mattcarroll): once this is proven to work, move this line ot TextInputPlugin @@ -597,6 +631,9 @@ public void detachFromFlutterEngine() { listener.onFlutterEngineDetachedFromFlutterView(); } + // Disconnect the FlutterEngine's PlatformViewsController from the AccessibilityBridge. + flutterEngine.getPlatformViewsController().detachAccessibiltyBridge(); + // Disconnect and clean up the AccessibilityBridge. accessibilityBridge.release(); accessibilityBridge = null; diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java b/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java index 08ed9f75004f7..3e2fb2b1c2644 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java @@ -29,6 +29,7 @@ import io.flutter.embedding.engine.systemchannels.SettingsChannel; import io.flutter.embedding.engine.systemchannels.SystemChannel; import io.flutter.embedding.engine.systemchannels.TextInputChannel; +import io.flutter.plugin.platform.PlatformViewsController; /** * A single Flutter execution environment. @@ -88,6 +89,11 @@ public class FlutterEngine implements LifecycleOwner { @NonNull private final TextInputChannel textInputChannel; + // Platform Views. + @NonNull + private final PlatformViewsController platformViewsController; + + // Engine Lifecycle. @NonNull private final Set engineLifecycleListeners = new HashSet<>(); @NonNull @@ -138,6 +144,8 @@ public FlutterEngine(@NonNull Context context) { systemChannel = new SystemChannel(dartExecutor); textInputChannel = new TextInputChannel(dartExecutor); + platformViewsController = new PlatformViewsController(); + androidLifecycle = new FlutterEngineAndroidLifecycle(this); this.pluginRegistry = new FlutterEnginePluginRegistry( context.getApplicationContext(), @@ -300,6 +308,15 @@ public PluginRegistry getPlugins() { return pluginRegistry; } + /** + * {@code PlatformViewsController}, which controls all platform views running within + * this {@code FlutterEngine}. + */ + @NonNull + public PlatformViewsController getPlatformViewsController() { + return platformViewsController; + } + @NonNull public ActivityControlSurface getActivityControlSurface() { return pluginRegistry; diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterEnginePluginRegistry.java b/shell/platform/android/io/flutter/embedding/engine/FlutterEnginePluginRegistry.java index 370ac44605e49..173aa915e663c 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterEnginePluginRegistry.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterEnginePluginRegistry.java @@ -34,13 +34,14 @@ import io.flutter.embedding.engine.plugins.service.ServiceAware; import io.flutter.embedding.engine.plugins.service.ServiceControlSurface; import io.flutter.embedding.engine.plugins.service.ServicePluginBinding; +import io.flutter.plugin.platform.PlatformViewsController; class FlutterEnginePluginRegistry implements PluginRegistry, ActivityControlSurface, ServiceControlSurface, BroadcastReceiverControlSurface, ContentProviderControlSurface { - private static final String TAG = "EnginePluginRegistry"; + private static final String TAG = "FlutterEnginePluginRegistry"; // PluginRegistry @NonNull @@ -277,7 +278,10 @@ private boolean isAttachedToActivity() { } @Override - public void attachToActivity(@NonNull Activity activity, @NonNull Lifecycle lifecycle) { + public void attachToActivity( + @NonNull Activity activity, + @NonNull Lifecycle lifecycle + ) { Log.v(TAG, "Attaching to an Activity: " + activity + "." + (isWaitingForActivityReattachment ? " This is after a config change." : "")); // If we were already attached to an Android component, detach from it. @@ -287,6 +291,15 @@ public void attachToActivity(@NonNull Activity activity, @NonNull Lifecycle life this.activityPluginBinding = new FlutterEngineActivityPluginBinding(activity); this.flutterEngineAndroidLifecycle.setBackingLifecycle(lifecycle); + // Activate the PlatformViewsController. This must happen before any plugins attempt + // to use it, otherwise an error stack trace will appear that says there is no + // flutter/platform_views channel. + pluginBinding.getFlutterEngine().getPlatformViewsController().attach( + activity, + pluginBinding.getFlutterEngine().getRenderer(), + pluginBinding.getFlutterEngine().getDartExecutor() + ); + // Notify all ActivityAware plugins that they are now attached to a new Activity. for (ActivityAware activityAware : activityAwarePlugins.values()) { if (isWaitingForActivityReattachment) { @@ -308,6 +321,9 @@ public void detachFromActivityForConfigChanges() { activityAware.onDetachedFromActivityForConfigChanges(); } + // Deactivate PlatformViewsController. + pluginBinding.getFlutterEngine().getPlatformViewsController().detach(); + flutterEngineAndroidLifecycle.setBackingLifecycle(null); activity = null; activityPluginBinding = null; @@ -324,6 +340,9 @@ public void detachFromActivity() { activityAware.onDetachedFromActivity(); } + // Deactivate PlatformViewsController. + pluginBinding.getFlutterEngine().getPlatformViewsController().detach(); + flutterEngineAndroidLifecycle.setBackingLifecycle(null); activity = null; activityPluginBinding = null; @@ -516,28 +535,17 @@ public FlutterEngineActivityPluginBinding(@NonNull Activity activity) { this.activity = activity; } - /** - * Returns the {@link Activity} that is currently attached to the {@link FlutterEngine} that - * owns this {@code ActivityPluginBinding}. - */ @Override @NonNull public Activity getActivity() { return activity; } - /** - * Adds a listener that is invoked whenever the associated {@link Activity}'s - * {@code onRequestPermissionsResult(...)} method is invoked. - */ @Override public void addRequestPermissionsResultListener(@NonNull io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener listener) { onRequestPermissionsResultListeners.add(listener); } - /** - * Removes a listener that was added in {@link #addRequestPermissionsResultListener(io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener)}. - */ @Override public void removeRequestPermissionsResultListener(@NonNull io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener listener) { onRequestPermissionsResultListeners.remove(listener); @@ -555,18 +563,11 @@ boolean onRequestPermissionsResult(int requestCode, @NonNull String[] permission return didConsumeResult; } - /** - * Adds a listener that is invoked whenever the associated {@link Activity}'s - * {@code onActivityResult(...)} method is invoked. - */ @Override public void addActivityResultListener(@NonNull io.flutter.plugin.common.PluginRegistry.ActivityResultListener listener) { onActivityResultListeners.add(listener); } - /** - * Removes a listener that was added in {@link #addActivityResultListener(io.flutter.plugin.common.PluginRegistry.ActivityResultListener)}. - */ @Override public void removeActivityResultListener(@NonNull io.flutter.plugin.common.PluginRegistry.ActivityResultListener listener) { onActivityResultListeners.remove(listener); @@ -584,18 +585,11 @@ boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent data) return didConsumeResult; } - /** - * Adds a listener that is invoked whenever the associated {@link Activity}'s - * {@code onNewIntent(...)} method is invoked. - */ @Override public void addOnNewIntentListener(@NonNull io.flutter.plugin.common.PluginRegistry.NewIntentListener listener) { onNewIntentListeners.add(listener); } - /** - * Removes a listener that was added in {@link #addOnNewIntentListener(io.flutter.plugin.common.PluginRegistry.NewIntentListener)}. - */ @Override public void removeOnNewIntentListener(@NonNull io.flutter.plugin.common.PluginRegistry.NewIntentListener listener) { onNewIntentListeners.remove(listener); @@ -611,18 +605,11 @@ void onNewIntent(@Nullable Intent intent) { } } - /** - * Adds a listener that is invoked whenever the associated {@link Activity}'s - * {@code onUserLeaveHint()} method is invoked. - */ @Override public void addOnUserLeaveHintListener(@NonNull io.flutter.plugin.common.PluginRegistry.UserLeaveHintListener listener) { onUserLeaveHintListeners.add(listener); } - /** - * Removes a listener that was added in {@link #addOnUserLeaveHintListener(io.flutter.plugin.common.PluginRegistry.UserLeaveHintListener)}. - */ @Override public void removeOnUserLeaveHintListener(@NonNull io.flutter.plugin.common.PluginRegistry.UserLeaveHintListener listener) { onUserLeaveHintListeners.remove(listener); diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index 9dca768d8fdb9..c478cea46ab0a 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -419,6 +419,7 @@ private native void nativeDispatchPointerDataPacket(long nativePlatformViewId, * See {@link AccessibilityBridge} for an example of an {@link AccessibilityDelegate} and the * surrounding responsibilities. */ + // TODO(mattcarroll): move AccessibilityDelegate definition into FlutterJNI. FlutterJNI should be the basis of dependencies, not the other way round. @UiThread public void setAccessibilityDelegate(@Nullable AccessibilityDelegate accessibilityDelegate) { ensureRunningOnMainThread(); diff --git a/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityControlSurface.java b/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityControlSurface.java index c5833eca7ce67..0f51c78d9595f 100644 --- a/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityControlSurface.java +++ b/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityControlSurface.java @@ -10,6 +10,8 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import io.flutter.plugin.platform.PlatformViewsController; + /** * Control surface through which an {@link Activity} attaches to a {@link FlutterEngine}. *

    diff --git a/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityPluginBinding.java b/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityPluginBinding.java index 9420c43c57b10..2958d79a81322 100644 --- a/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityPluginBinding.java +++ b/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityPluginBinding.java @@ -8,6 +8,7 @@ import android.support.annotation.NonNull; import io.flutter.plugin.common.PluginRegistry; +import io.flutter.plugin.platform.PlatformViewsController; /** * Binding that gives {@link ActivityAware} plugins access to an associated {@link Activity} and diff --git a/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimPluginRegistry.java b/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimPluginRegistry.java index ce85eb0f37c90..011eea303bab1 100644 --- a/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimPluginRegistry.java +++ b/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimPluginRegistry.java @@ -4,7 +4,6 @@ package io.flutter.embedding.engine.plugins.shim; -import android.app.Activity; import android.support.annotation.NonNull; import java.util.HashMap; @@ -18,8 +17,6 @@ import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.plugin.common.PluginRegistry; -import io.flutter.plugin.platform.PlatformViewsController; -import io.flutter.view.FlutterView; /** * A {@link PluginRegistry} that is shimmed to use the new Android embedding and plugin API behind @@ -41,24 +38,11 @@ public class ShimPluginRegistry implements PluginRegistry { private static final String TAG = "ShimPluginRegistry"; private final FlutterEngine flutterEngine; - private final PlatformViewsController platformViewsController; private final Map pluginMap = new HashMap<>(); private final ShimRegistrarAggregate shimRegistrarAggregate; - private final FlutterEngine.EngineLifecycleListener engineLifecycleListener = new FlutterEngine.EngineLifecycleListener() { - @Override - public void onPreEngineRestart() { - Log.v(TAG, "onPreEngineRestart()"); - ShimPluginRegistry.this.onPreEngineRestart(); - } - }; - public ShimPluginRegistry( - @NonNull FlutterEngine flutterEngine, - @NonNull PlatformViewsController platformViewsController - ) { + public ShimPluginRegistry(@NonNull FlutterEngine flutterEngine) { this.flutterEngine = flutterEngine; - this.flutterEngine.addEngineLifecycleListener(engineLifecycleListener); - this.platformViewsController = platformViewsController; this.shimRegistrarAggregate = new ShimRegistrarAggregate(); this.flutterEngine.getPlugins().add(shimRegistrarAggregate); } @@ -86,26 +70,6 @@ public T valuePublishedByPlugin(String pluginKey) { return (T) pluginMap.get(pluginKey); } - //----- From FlutterPluginRegistry that aren't in the PluginRegistry interface ----// - public void attach(FlutterView flutterView, Activity activity) { - Log.v(TAG, "Attaching to a FlutterView and an Activity."); - platformViewsController.attach(activity, flutterEngine.getRenderer(), flutterEngine.getDartExecutor()); - } - - public void detach() { - Log.v(TAG, "Detaching from a FlutterView and an Activity."); - platformViewsController.detach(); - platformViewsController.onFlutterViewDestroyed(); - } - - private void onPreEngineRestart() { - platformViewsController.onPreEngineRestart(); - } - - public PlatformViewsController getPlatformViewsController() { - return platformViewsController; - } - /** * Aggregates all {@link ShimRegistrar}s within one single {@link FlutterPlugin}. *

    diff --git a/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimRegistrar.java b/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimRegistrar.java index e6bb8e50c7860..39e5ea5764353 100644 --- a/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimRegistrar.java +++ b/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimRegistrar.java @@ -74,7 +74,7 @@ public TextureRegistry textures() { @Override public PlatformViewRegistry platformViewRegistry() { - return null; + return pluginBinding != null ? pluginBinding.getFlutterEngine().getPlatformViewsController().getRegistry() : null; } @Override