5package io.flutter.embedding.engine.systemchannels;
7import android.content.pm.ActivityInfo;
8import androidx.annotation.NonNull;
9import androidx.annotation.Nullable;
10import androidx.annotation.VisibleForTesting;
12import io.flutter.embedding.engine.dart.DartExecutor;
13import io.flutter.plugin.common.JSONMethodCodec;
14import io.flutter.plugin.common.MethodCall;
15import io.flutter.plugin.common.MethodChannel;
16import java.util.ArrayList;
17import java.util.Arrays;
19import org.json.JSONArray;
20import org.json.JSONException;
21import org.json.JSONObject;
28 private static final String TAG =
"PlatformChannel";
33 @NonNull @VisibleForTesting
38 if (platformMessageHandler ==
null) {
44 String method =
call.method;
45 Object arguments =
call.arguments;
46 Log.
v(
TAG,
"Received '" + method +
"' message.");
49 case "SystemSound.play":
52 platformMessageHandler.playSystemSound(soundType);
54 }
catch (NoSuchFieldException exception) {
56 result.error(
"error", exception.getMessage(),
null);
59 case "HapticFeedback.vibrate":
63 platformMessageHandler.vibrateHapticFeedback(feedbackType);
65 }
catch (NoSuchFieldException exception) {
67 result.error(
"error", exception.getMessage(),
null);
70 case "SystemChrome.setPreferredOrientations":
72 int androidOrientation = decodeOrientations((JSONArray) arguments);
73 platformMessageHandler.setPreferredOrientations(androidOrientation);
75 }
catch (JSONException | NoSuchFieldException exception) {
80 result.error(
"error", exception.getMessage(),
null);
83 case "SystemChrome.setApplicationSwitcherDescription":
86 decodeAppSwitcherDescription((JSONObject) arguments);
87 platformMessageHandler.setApplicationSwitcherDescription(description);
89 }
catch (JSONException exception) {
91 result.error(
"error", exception.getMessage(),
null);
94 case "SystemChrome.setEnabledSystemUIOverlays":
97 platformMessageHandler.showSystemOverlays(overlays);
99 }
catch (JSONException | NoSuchFieldException exception) {
103 result.error(
"error", exception.getMessage(),
null);
106 case "SystemChrome.setEnabledSystemUIMode":
109 platformMessageHandler.showSystemUiMode(
mode);
111 }
catch (JSONException | NoSuchFieldException exception) {
115 result.error(
"error", exception.getMessage(),
null);
118 case "SystemChrome.setSystemUIChangeListener":
119 platformMessageHandler.setSystemUiChangeListener();
122 case "SystemChrome.restoreSystemUIOverlays":
123 platformMessageHandler.restoreSystemUiOverlays();
126 case "SystemChrome.setSystemUIOverlayStyle":
129 decodeSystemChromeStyle((JSONObject) arguments);
130 platformMessageHandler.setSystemUiOverlayStyle(systemChromeStyle);
132 }
catch (JSONException | NoSuchFieldException exception) {
136 result.error(
"error", exception.getMessage(),
null);
139 case "SystemNavigator.setFrameworkHandlesBack":
141 boolean frameworkHandlesBack = (boolean) arguments;
142 platformMessageHandler.setFrameworkHandlesBack(frameworkHandlesBack);
146 case "SystemNavigator.pop":
147 platformMessageHandler.popSystemNavigator();
150 case "Clipboard.getData":
152 String contentFormatName = (String) arguments;
154 if (contentFormatName !=
null) {
157 }
catch (NoSuchFieldException exception) {
160 "error",
"No such clipboard content format: " + contentFormatName,
null);
164 CharSequence clipboardContent =
165 platformMessageHandler.getClipboardData(clipboardFormat);
166 if (clipboardContent !=
null) {
167 JSONObject response =
new JSONObject();
168 response.put(
"text", clipboardContent);
175 case "Clipboard.setData":
177 String clipboardContent = ((JSONObject) arguments).getString(
"text");
178 platformMessageHandler.setClipboardData(clipboardContent);
182 case "Clipboard.hasStrings":
184 boolean hasStrings = platformMessageHandler.clipboardHasStrings();
185 JSONObject response =
new JSONObject();
186 response.put(
"value", hasStrings);
191 String
text = (String) arguments;
192 platformMessageHandler.share(
text);
199 }
catch (JSONException
e) {
200 result.error(
"error",
"JSON error: " +
e.getMessage(),
null);
223 this.platformMessageHandler = platformMessageHandler;
228 Log.
v(
TAG,
"Sending 'systemUIChange' message.");
241 private int decodeOrientations(@NonNull JSONArray encodedOrientations)
242 throws JSONException, NoSuchFieldException {
243 int requestedOrientation = 0x00;
244 int firstRequestedOrientation = 0x00;
245 for (
int index = 0; index < encodedOrientations.length(); index += 1) {
246 String encodedOrientation = encodedOrientations.getString(index);
247 DeviceOrientation orientation = DeviceOrientation.fromValue(encodedOrientation);
249 switch (orientation) {
251 requestedOrientation |= 0x01;
254 requestedOrientation |= 0x04;
257 requestedOrientation |= 0x02;
259 case LANDSCAPE_RIGHT:
260 requestedOrientation |= 0x08;
264 if (firstRequestedOrientation == 0x00) {
265 firstRequestedOrientation = requestedOrientation;
269 switch (requestedOrientation) {
271 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
273 return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
275 return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
277 return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
279 return ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT;
281 return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
283 return ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE;
285 return ActivityInfo.SCREEN_ORIENTATION_USER;
287 return ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
297 switch (firstRequestedOrientation) {
299 return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
301 return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
303 return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
305 return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
311 return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
315 private AppSwitcherDescription decodeAppSwitcherDescription(
316 @NonNull JSONObject encodedDescription)
throws JSONException {
317 int color = encodedDescription.getInt(
"primaryColor");
321 String label = encodedDescription.getString(
"label");
322 return new AppSwitcherDescription(
color, label);
334 throws JSONException, NoSuchFieldException {
336 for (
int i = 0;
i < encodedSystemUiOverlay.length(); ++
i) {
337 String encodedOverlay = encodedSystemUiOverlay.getString(
i);
338 SystemUiOverlay overlay = SystemUiOverlay.fromValue(encodedOverlay);
341 overlays.
add(SystemUiOverlay.TOP_OVERLAYS);
343 case BOTTOM_OVERLAYS:
344 overlays.
add(SystemUiOverlay.BOTTOM_OVERLAYS);
359 private SystemUiMode decodeSystemUiMode(@NonNull String encodedSystemUiMode)
360 throws JSONException, NoSuchFieldException {
361 SystemUiMode
mode = SystemUiMode.fromValue(encodedSystemUiMode);
364 return SystemUiMode.LEAN_BACK;
366 return SystemUiMode.IMMERSIVE;
367 case IMMERSIVE_STICKY:
368 return SystemUiMode.IMMERSIVE_STICKY;
370 return SystemUiMode.EDGE_TO_EDGE;
374 return SystemUiMode.EDGE_TO_EDGE;
384 private SystemChromeStyle decodeSystemChromeStyle(@NonNull JSONObject encodedStyle)
385 throws JSONException, NoSuchFieldException {
387 Integer statusBarColor =
null;
388 Brightness statusBarIconBrightness =
null;
389 Boolean systemStatusBarContrastEnforced =
null;
391 Integer systemNavigationBarColor =
null;
392 Brightness systemNavigationBarIconBrightness =
null;
394 Integer systemNavigationBarDividerColor =
null;
395 Boolean systemNavigationBarContrastEnforced =
null;
397 if (!encodedStyle.isNull(
"statusBarColor")) {
398 statusBarColor = encodedStyle.getInt(
"statusBarColor");
401 if (!encodedStyle.isNull(
"statusBarIconBrightness")) {
402 statusBarIconBrightness =
403 Brightness.fromValue(encodedStyle.getString(
"statusBarIconBrightness"));
406 if (!encodedStyle.isNull(
"systemStatusBarContrastEnforced")) {
407 systemStatusBarContrastEnforced = encodedStyle.getBoolean(
"systemStatusBarContrastEnforced");
410 if (!encodedStyle.isNull(
"systemNavigationBarColor")) {
411 systemNavigationBarColor = encodedStyle.getInt(
"systemNavigationBarColor");
414 if (!encodedStyle.isNull(
"systemNavigationBarIconBrightness")) {
415 systemNavigationBarIconBrightness =
416 Brightness.fromValue(encodedStyle.getString(
"systemNavigationBarIconBrightness"));
419 if (!encodedStyle.isNull(
"systemNavigationBarDividerColor")) {
420 systemNavigationBarDividerColor = encodedStyle.getInt(
"systemNavigationBarDividerColor");
423 if (!encodedStyle.isNull(
"systemNavigationBarContrastEnforced")) {
424 systemNavigationBarContrastEnforced =
425 encodedStyle.getBoolean(
"systemNavigationBarContrastEnforced");
428 return new SystemChromeStyle(
430 statusBarIconBrightness,
431 systemStatusBarContrastEnforced,
432 systemNavigationBarColor,
433 systemNavigationBarIconBrightness,
434 systemNavigationBarDividerColor,
435 systemNavigationBarContrastEnforced);
574 if (soundType.encodedName.equals(encodedName)) {
578 throw new NoSuchFieldException(
"No such SoundType: " + encodedName);
581 @NonNull
private final String encodedName;
584 this.encodedName = encodedName;
599 if ((feedbackType.encodedName ==
null && encodedName ==
null)
600 || (feedbackType.encodedName !=
null && feedbackType.encodedName.equals(encodedName))) {
604 throw new NoSuchFieldException(
"No such HapticFeedbackType: " + encodedName);
607 @Nullable
private final String encodedName;
610 this.encodedName = encodedName;
624 if (orientation.encodedName.equals(encodedName)) {
628 throw new NoSuchFieldException(
"No such DeviceOrientation: " + encodedName);
631 @NonNull
private String encodedName;
634 this.encodedName = encodedName;
652 if (overlay.encodedName.equals(encodedName)) {
656 throw new NoSuchFieldException(
"No such SystemUiOverlay: " + encodedName);
659 @NonNull
private String encodedName;
662 this.encodedName = encodedName;
680 if (
mode.encodedName.equals(encodedName)) {
684 throw new NoSuchFieldException(
"No such SystemUiMode: " + encodedName);
687 @NonNull
private String encodedName;
691 this.encodedName = encodedName;
748 if (brightness.encodedName.equals(encodedName)) {
752 throw new NoSuchFieldException(
"No such Brightness: " + encodedName);
755 @NonNull
private String encodedName;
758 this.encodedName = encodedName;
768 throws NoSuchFieldException {
770 if (
format.encodedName.equals(encodedName)) {
774 throw new NoSuchFieldException(
"No such ClipboardContentFormat: " + encodedName);
777 @NonNull
private String encodedName;
780 this.encodedName = encodedName;
void add(sk_sp< SkIDChangeListener > listener) SK_EXCLUDES(fMutex)
static void v(@NonNull String tag, @NonNull String message)
static final JSONMethodCodec INSTANCE
void setMethodCallHandler(final @Nullable MethodCallHandler handler)
void invokeMethod(@NonNull String method, @Nullable Object arguments)
static ClipboardContentFormat fromValue(@NonNull String encodedName)
ClipboardContentFormat(@NonNull String encodedName)
uint32_t uint32_t * format
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode