Flutter Engine
The Flutter Engine
DeferredComponentChannel.java
Go to the documentation of this file.
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
5package io.flutter.embedding.engine.systemchannels;
6
7import androidx.annotation.NonNull;
8import androidx.annotation.Nullable;
9import androidx.annotation.VisibleForTesting;
10import io.flutter.FlutterInjector;
11import io.flutter.Log;
12import io.flutter.embedding.engine.dart.DartExecutor;
13import io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager;
14import io.flutter.plugin.common.MethodCall;
15import io.flutter.plugin.common.MethodChannel;
16import io.flutter.plugin.common.StandardMethodCodec;
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.List;
20import java.util.Map;
21
22/**
23 * Method channel that handles manual installation requests and queries for installation state for
24 * deferred components.
25 *
26 * <p>This channel is able to handle multiple simultaneous installation requests
27 */
29 private static final String TAG = "DeferredComponentChannel";
30
31 @NonNull private final MethodChannel channel;
32 @Nullable private DeferredComponentManager deferredComponentManager;
33 // Track the Result objects to be able to handle multiple install requests of
34 // the same components at a time. When installation enters a terminal state, either
35 // completeInstallSuccess or completeInstallError can be called.
36 @NonNull private Map<String, List<MethodChannel.Result>> componentNameToResults;
37
38 @NonNull @VisibleForTesting
39 final MethodChannel.MethodCallHandler parsingMethodHandler =
41 @Override
42 public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
43 if (deferredComponentManager == null) {
44 // If no DeferredComponentManager has been injected, then this channel is a no-op.
45 return;
46 }
47 String method = call.method;
48 Map<String, Object> args = call.arguments();
49 Log.v(TAG, "Received '" + method + "' message.");
50 final int loadingUnitId = (int) args.get("loadingUnitId");
51 final String componentName = (String) args.get("componentName");
52 switch (method) {
53 case "installDeferredComponent":
54 deferredComponentManager.installDeferredComponent(loadingUnitId, componentName);
55 if (!componentNameToResults.containsKey(componentName)) {
56 componentNameToResults.put(componentName, new ArrayList<>());
57 }
58 componentNameToResults.get(componentName).add(result);
59 break;
60 case "getDeferredComponentInstallState":
61 result.success(
62 deferredComponentManager.getDeferredComponentInstallState(
63 loadingUnitId, componentName));
64 break;
65 case "uninstallDeferredComponent":
66 deferredComponentManager.uninstallDeferredComponent(loadingUnitId, componentName);
67 result.success(null);
68 break;
69 default:
70 result.notImplemented();
71 break;
72 }
73 }
74 };
75
76 /**
77 * Constructs a {@code DeferredComponentChannel} that connects Android to the Dart code running in
78 * {@code dartExecutor}.
79 *
80 * <p>The given {@code dartExecutor} is permitted to be idle or executing code.
81 *
82 * <p>See {@link DartExecutor}.
83 */
84 public DeferredComponentChannel(@NonNull DartExecutor dartExecutor) {
85 this.channel =
86 new MethodChannel(dartExecutor, "flutter/deferredcomponent", StandardMethodCodec.INSTANCE);
87 channel.setMethodCallHandler(parsingMethodHandler);
88 deferredComponentManager = FlutterInjector.instance().deferredComponentManager();
89 componentNameToResults = new HashMap<>();
90 }
91
92 /**
93 * Sets the DeferredComponentManager to exectue method channel calls with.
94 *
95 * @param deferredComponentManager the DeferredComponentManager to use.
96 */
97 @VisibleForTesting
99 @Nullable DeferredComponentManager deferredComponentManager) {
100 this.deferredComponentManager = deferredComponentManager;
101 }
102
103 /**
104 * Finishes the `installDeferredComponent` method channel call for the specified componentName
105 * with a success.
106 *
107 * @param componentName The name of the android deferred component install request to complete.
108 */
109 public void completeInstallSuccess(String componentName) {
110 if (componentNameToResults.containsKey(componentName)) {
111 for (MethodChannel.Result result : componentNameToResults.get(componentName)) {
112 result.success(null);
113 }
114 componentNameToResults.get(componentName).clear();
115 }
116 return;
117 }
118
119 /**
120 * Finishes the `installDeferredComponent` method channel call for the specified componentName
121 * with an error/failure.
122 *
123 * @param componentName The name of the android deferred component install request to complete.
124 * @param errorMessage The error message to display to complete the future with.
125 */
126 public void completeInstallError(String componentName, String errorMessage) {
127 if (componentNameToResults.containsKey(componentName)) {
128 for (MethodChannel.Result result : componentNameToResults.get(componentName)) {
129 result.error("DeferredComponent Install failure", errorMessage, null);
130 }
131 componentNameToResults.get(componentName).clear();
132 }
133 return;
134 }
135}
static void v(@NonNull String tag, @NonNull String message)
Definition: Log.java:40
void setDeferredComponentManager( @Nullable DeferredComponentManager deferredComponentManager)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
def call(args)
Definition: dom.py:159
#define TAG()