• 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;
6 
7 import android.arch.lifecycle.Lifecycle;
8 import android.arch.lifecycle.LifecycleOwner;
9 import android.content.Context;
10 import android.support.annotation.NonNull;
11 
12 import io.flutter.embedding.engine.FlutterEngine;
13 
14 /**
15  * Interface to be implemented by all Flutter plugins.
16  * <p>
17  * A Flutter plugin allows Flutter developers to interact with a host platform, e.g., Android and
18  * iOS, via Dart code. It includes platform code, as well as Dart code. A plugin author is
19  * responsible for setting up an appropriate {@link io.flutter.plugin.common.MethodChannel}
20  * to communicate between platform code and Dart code.
21  * <p>
22  * A Flutter plugin has a lifecycle. First, a developer must add a {@code FlutterPlugin} to an
23  * instance of {@link FlutterEngine}. To do this, obtain a {@link PluginRegistry} with
24  * {@link FlutterEngine#getPlugins()}, then call {@link PluginRegistry#add(FlutterPlugin)},
25  * passing the instance of the Flutter plugin. During the call to
26  * {@link PluginRegistry#add(FlutterPlugin)}, the {@link FlutterEngine} will invoke
27  * {@link #onAttachedToEngine(FlutterPluginBinding)} on the given {@code FlutterPlugin}. If the
28  * {@code FlutterPlugin} is removed from the {@link FlutterEngine} via
29  * {@link PluginRegistry#remove(Class)}, or if the {@link FlutterEngine} is destroyed, the
30  * {@link FlutterEngine} will invoke {@link FlutterPlugin#onDetachedFromEngine(FlutterPluginBinding)}
31  * on the given {@code FlutterPlugin}.
32  * <p>
33  * Once a {@code FlutterPlugin} is attached to a {@link FlutterEngine}, the plugin's code is
34  * permitted to access and invoke methods on resources within the {@link FlutterPluginBinding} that
35  * the {@link FlutterEngine} gave to the {@code FlutterPlugin} in
36  * {@link #onAttachedToEngine(FlutterPluginBinding)}. This includes, for example, the application
37  * {@link Context} for the running app.
38  * <p>
39  * The {@link FlutterPluginBinding} provided in {@link #onAttachedToEngine(FlutterPluginBinding)}
40  * is no longer valid after the execution of {@link #onDetachedFromEngine(FlutterPluginBinding)}.
41  * Do not access any properties of the {@link FlutterPluginBinding} after the completion of
42  * {@link #onDetachedFromEngine(FlutterPluginBinding)}.
43  * <p>
44  * The Android side of a Flutter plugin can be thought of as applying itself to a {@link FlutterEngine}.
45  * Use {@link FlutterPluginBinding#getFlutterEngine()} to retrieve the {@link FlutterEngine} that
46  * the {@code FlutterPlugin} is attached to. To register a
47  * {@link io.flutter.plugin.common.MethodChannel}, obtain the {@link FlutterEngine}'s
48  * {@link io.flutter.embedding.engine.dart.DartExecutor} with {@link FlutterEngine#getDartExecutor()},
49  * then pass the {@link io.flutter.embedding.engine.dart.DartExecutor} to the
50  * {@link io.flutter.plugin.common.MethodChannel} as a {@link io.flutter.plugin.common.BinaryMessenger}.
51  * <p>
52  * An Android Flutter plugin may require access to app resources or other artifacts that can only
53  * be retrieved through a {@link Context}. Developers can access the application context via
54  * {@link FlutterPluginBinding#getApplicationContext()}.
55  * <p>
56  * TODO(mattcarroll): explain ActivityAware when it's added to the new plugin API surface.
57  */
58 public interface FlutterPlugin {
59 
60   /**
61    * This {@code FlutterPlugin} has been associated with a {@link FlutterEngine} instance.
62    * <p>
63    * Relevant resources that this {@code FlutterPlugin} may need are provided via the {@code binding}.
64    * The {@code binding} may be cached and referenced until
65    * {@link #onDetachedFromEngine(FlutterPluginBinding)} is invoked and returns.
66    */
onAttachedToEngine(@onNull FlutterPluginBinding binding)67   void onAttachedToEngine(@NonNull FlutterPluginBinding binding);
68 
69   /**
70    * This {@code FlutterPlugin} has been removed from a {@link FlutterEngine} instance.
71    * <p>
72    * The {@code binding} passed to this method is the same instance that was passed in
73    * {@link #onAttachedToEngine(FlutterPluginBinding)}. It is provided again in this method as a
74    * convenience. The {@code binding} may be referenced during the execution of this method, but
75    * it must not be cached or referenced after this method returns.
76    * <p>
77    * {@code FlutterPlugin}s should release all resources in this method.
78    */
onDetachedFromEngine(@onNull FlutterPluginBinding binding)79   void onDetachedFromEngine(@NonNull FlutterPluginBinding binding);
80 
81   /**
82    * Resources made available to all plugins registered with a given {@link FlutterEngine}.
83    * <p>
84    * The {@code FlutterPluginBinding}'s {@code flutterEngine} refers to the {@link FlutterEngine}
85    * that the associated {@code FlutterPlugin} is intended to apply to. For example, if a
86    * {@code FlutterPlugin} needs to setup a communication channel with its associated Flutter app,
87    * that can be done by wrapping a {@code MethodChannel} around
88    * {@link FlutterEngine#getDartExecutor()}.
89    * <p>
90    * A {@link FlutterEngine} may move from foreground to background, from an {@code Activity} to
91    * a {@code Service}. {@code FlutterPluginBinding}'s {@code lifecycle} generalizes those
92    * lifecycles so that a {@code FlutterPlugin} can react to lifecycle events without being
93    * concerned about which Android Component is currently holding the {@link FlutterEngine}.
94    * TODO(mattcarroll): add info about ActivityAware and ServiceAware for plugins that care.
95    */
96   class FlutterPluginBinding implements LifecycleOwner {
97         private final Context applicationContext;
98         private final FlutterEngine flutterEngine;
99         private final Lifecycle lifecycle;
100 
FlutterPluginBinding( @onNull Context applicationContext, @NonNull FlutterEngine flutterEngine, @NonNull Lifecycle lifecycle )101         public FlutterPluginBinding(
102             @NonNull Context applicationContext,
103             @NonNull FlutterEngine flutterEngine,
104             @NonNull Lifecycle lifecycle
105         ) {
106             this.applicationContext = applicationContext;
107             this.flutterEngine = flutterEngine;
108             this.lifecycle = lifecycle;
109         }
110 
111         @NonNull
getApplicationContext()112         public Context getApplicationContext() {
113             return applicationContext;
114         }
115 
116         @NonNull
getFlutterEngine()117         public FlutterEngine getFlutterEngine() {
118             return flutterEngine;
119         }
120 
121         @Override
122         @NonNull
getLifecycle()123         public Lifecycle getLifecycle() {
124             return lifecycle;
125         }
126     }
127 }
128