Skip to content

Commit

Permalink
Fixes a plugin overwrite bug in the plugin shim system. (#9589)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthew-carroll committed Jul 1, 2019
1 parent 345d350 commit 628b174
Showing 1 changed file with 86 additions and 1 deletion.
Expand Up @@ -8,10 +8,15 @@
import android.support.annotation.NonNull;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import io.flutter.Log;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
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;
Expand All @@ -38,6 +43,7 @@ public class ShimPluginRegistry implements PluginRegistry {
private final FlutterEngine flutterEngine;
private final PlatformViewsController platformViewsController;
private final Map<String, Object> pluginMap = new HashMap<>();
private final ShimRegistrarAggregate shimRegistrarAggregate;
private final FlutterEngine.EngineLifecycleListener engineLifecycleListener = new FlutterEngine.EngineLifecycleListener() {
@Override
public void onPreEngineRestart() {
Expand All @@ -53,6 +59,8 @@ public ShimPluginRegistry(
this.flutterEngine = flutterEngine;
this.flutterEngine.addEngineLifecycleListener(engineLifecycleListener);
this.platformViewsController = platformViewsController;
this.shimRegistrarAggregate = new ShimRegistrarAggregate();
this.flutterEngine.getPlugins().add(shimRegistrarAggregate);
}

@Override
Expand All @@ -63,7 +71,7 @@ public Registrar registrarFor(String pluginKey) {
}
pluginMap.put(pluginKey, null);
ShimRegistrar registrar = new ShimRegistrar(pluginKey, pluginMap);
flutterEngine.getPlugins().add(registrar);
shimRegistrarAggregate.addPlugin(registrar);
return registrar;
}

Expand Down Expand Up @@ -97,4 +105,81 @@ private void onPreEngineRestart() {
public PlatformViewsController getPlatformViewsController() {
return platformViewsController;
}

/**
* Aggregates all {@link ShimRegistrar}s within one single {@link FlutterPlugin}.
* <p>
* The reason we need this aggregate is because the new embedding uniquely identifies
* plugins by their plugin class, but the plugin shim system represents every plugin
* with a {@link ShimRegistrar}. Therefore, every plugin we would register after the first
* plugin, would overwrite the previous plugin, because they're all {@link ShimRegistrar}
* instances.
* <p>
* {@code ShimRegistrarAggregate} multiplexes {@link FlutterPlugin} and {@link ActivityAware}
* calls so that we can register just one {@code ShimRegistrarAggregate} with a
* {@link FlutterEngine}, while forwarding the relevant plugin resources to any number
* of {@link ShimRegistrar}s within this {@code ShimRegistrarAggregate}.
*/
private static class ShimRegistrarAggregate implements FlutterPlugin, ActivityAware {
private final Set<ShimRegistrar> shimRegistrars = new HashSet<>();
private FlutterPluginBinding flutterPluginBinding;
private ActivityPluginBinding activityPluginBinding;

public void addPlugin(@NonNull ShimRegistrar shimRegistrar) {
shimRegistrars.add(shimRegistrar);

if (flutterPluginBinding != null) {
shimRegistrar.onAttachedToEngine(flutterPluginBinding);
}
if (activityPluginBinding != null) {
shimRegistrar.onAttachedToActivity(activityPluginBinding);
}
}

@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
flutterPluginBinding = binding;
for (ShimRegistrar shimRegistrar : shimRegistrars) {
shimRegistrar.onAttachedToEngine(binding);
}
}

@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
for (ShimRegistrar shimRegistrar : shimRegistrars) {
shimRegistrar.onDetachedFromEngine(binding);
}
flutterPluginBinding = null;
}

@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
activityPluginBinding = binding;
for (ShimRegistrar shimRegistrar : shimRegistrars) {
shimRegistrar.onAttachedToActivity(binding);
}
}

@Override
public void onDetachedFromActivityForConfigChanges() {
for (ShimRegistrar shimRegistrar : shimRegistrars) {
shimRegistrar.onDetachedFromActivity();
}
activityPluginBinding = null;
}

@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
for (ShimRegistrar shimRegistrar : shimRegistrars) {
shimRegistrar.onReattachedToActivityForConfigChanges(binding);
}
}

@Override
public void onDetachedFromActivity() {
for (ShimRegistrar shimRegistrar : shimRegistrars) {
shimRegistrar.onDetachedFromActivity();
}
}
}
}

0 comments on commit 628b174

Please sign in to comment.