blob: 9c40d0a016f2119cf916346b826117f7af432057 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.embedding.engine.plugins.shim;
import android.app.Activity;
import android.content.Context;
import androidx.annotation.NonNull;
import io.flutter.FlutterInjector;
import io.flutter.Log;
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.BinaryMessenger;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.platform.PlatformViewRegistry;
import io.flutter.view.FlutterView;
import io.flutter.view.TextureRegistry;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* A {@link PluginRegistry.Registrar} that is shimmed let old plugins use the new Android embedding
* and plugin API behind the scenes.
*
* <p>Instances of {@code ShimRegistrar}s are vended internally by a {@link ShimPluginRegistry}.
*/
class ShimRegistrar implements PluginRegistry.Registrar, FlutterPlugin, ActivityAware {
private static final String TAG = "ShimRegistrar";
private final Map<String, Object> globalRegistrarMap;
private final String pluginId;
private final Set<PluginRegistry.ViewDestroyListener> viewDestroyListeners = new HashSet<>();
private final Set<PluginRegistry.RequestPermissionsResultListener>
requestPermissionsResultListeners = new HashSet<>();
private final Set<PluginRegistry.ActivityResultListener> activityResultListeners =
new HashSet<>();
private final Set<PluginRegistry.NewIntentListener> newIntentListeners = new HashSet<>();
private final Set<PluginRegistry.UserLeaveHintListener> userLeaveHintListeners = new HashSet<>();
private FlutterPlugin.FlutterPluginBinding pluginBinding;
private ActivityPluginBinding activityPluginBinding;
public ShimRegistrar(@NonNull String pluginId, @NonNull Map<String, Object> globalRegistrarMap) {
this.pluginId = pluginId;
this.globalRegistrarMap = globalRegistrarMap;
}
@Override
public Activity activity() {
return activityPluginBinding != null ? activityPluginBinding.getActivity() : null;
}
@Override
public Context context() {
return pluginBinding != null ? pluginBinding.getApplicationContext() : null;
}
@Override
public Context activeContext() {
return activityPluginBinding == null ? context() : activity();
}
@Override
public BinaryMessenger messenger() {
return pluginBinding != null ? pluginBinding.getBinaryMessenger() : null;
}
@Override
public TextureRegistry textures() {
return pluginBinding != null ? pluginBinding.getTextureRegistry() : null;
}
@Override
public PlatformViewRegistry platformViewRegistry() {
return pluginBinding != null ? pluginBinding.getPlatformViewRegistry() : null;
}
@Override
public FlutterView view() {
throw new UnsupportedOperationException(
"The new embedding does not support the old FlutterView.");
}
@Override
public String lookupKeyForAsset(String asset) {
return FlutterInjector.instance().flutterLoader().getLookupKeyForAsset(asset);
}
@Override
public String lookupKeyForAsset(String asset, String packageName) {
return FlutterInjector.instance().flutterLoader().getLookupKeyForAsset(asset, packageName);
}
@Override
public PluginRegistry.Registrar publish(Object value) {
globalRegistrarMap.put(pluginId, value);
return this;
}
@Override
public PluginRegistry.Registrar addRequestPermissionsResultListener(
PluginRegistry.RequestPermissionsResultListener listener) {
requestPermissionsResultListeners.add(listener);
if (activityPluginBinding != null) {
activityPluginBinding.addRequestPermissionsResultListener(listener);
}
return this;
}
@Override
public PluginRegistry.Registrar addActivityResultListener(
PluginRegistry.ActivityResultListener listener) {
activityResultListeners.add(listener);
if (activityPluginBinding != null) {
activityPluginBinding.addActivityResultListener(listener);
}
return this;
}
@Override
public PluginRegistry.Registrar addNewIntentListener(PluginRegistry.NewIntentListener listener) {
newIntentListeners.add(listener);
if (activityPluginBinding != null) {
activityPluginBinding.addOnNewIntentListener(listener);
}
return this;
}
@Override
public PluginRegistry.Registrar addUserLeaveHintListener(
PluginRegistry.UserLeaveHintListener listener) {
userLeaveHintListeners.add(listener);
if (activityPluginBinding != null) {
activityPluginBinding.addOnUserLeaveHintListener(listener);
}
return this;
}
@Override
@NonNull
public PluginRegistry.Registrar addViewDestroyListener(
@NonNull PluginRegistry.ViewDestroyListener listener) {
viewDestroyListeners.add(listener);
return this;
}
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
Log.v(TAG, "Attached to FlutterEngine.");
pluginBinding = binding;
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
Log.v(TAG, "Detached from FlutterEngine.");
for (PluginRegistry.ViewDestroyListener listener : viewDestroyListeners) {
// The following invocation might produce unexpected behavior in old plugins because
// we have no FlutterNativeView to pass to onViewDestroy(). This is a limitation of this shim.
listener.onViewDestroy(null);
}
pluginBinding = null;
activityPluginBinding = null;
}
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
Log.v(TAG, "Attached to an Activity.");
activityPluginBinding = binding;
addExistingListenersToActivityPluginBinding();
}
@Override
public void onDetachedFromActivityForConfigChanges() {
Log.v(TAG, "Detached from an Activity for config changes.");
activityPluginBinding = null;
}
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
Log.v(TAG, "Reconnected to an Activity after config changes.");
activityPluginBinding = binding;
addExistingListenersToActivityPluginBinding();
}
@Override
public void onDetachedFromActivity() {
Log.v(TAG, "Detached from an Activity.");
activityPluginBinding = null;
}
private void addExistingListenersToActivityPluginBinding() {
for (PluginRegistry.RequestPermissionsResultListener listener :
requestPermissionsResultListeners) {
activityPluginBinding.addRequestPermissionsResultListener(listener);
}
for (PluginRegistry.ActivityResultListener listener : activityResultListeners) {
activityPluginBinding.addActivityResultListener(listener);
}
for (PluginRegistry.NewIntentListener listener : newIntentListeners) {
activityPluginBinding.addOnNewIntentListener(listener);
}
for (PluginRegistry.UserLeaveHintListener listener : userLeaveHintListeners) {
activityPluginBinding.addOnUserLeaveHintListener(listener);
}
}
}