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; 6 7 import android.content.Context; 8 import android.content.Intent; 9 import android.support.annotation.NonNull; 10 11 import java.util.*; 12 13 /** 14 * Arguments that can be delivered to the Flutter shell when it is created. 15 * <p> 16 * WARNING: THIS CLASS IS EXPERIMENTAL. DO NOT SHIP A DEPENDENCY ON THIS CODE. 17 * IF YOU USE IT, WE WILL BREAK YOU. 18 * <p> 19 * The term "shell" refers to the native code that adapts Flutter to different platforms. Flutter's 20 * Android Java code initializes a native "shell" and passes these arguments to that native shell 21 * when it is initialized. See {@link io.flutter.view.FlutterMain#ensureInitializationComplete(Context, String[])} 22 * for more information. 23 */ 24 @SuppressWarnings({"WeakerAccess", "unused"}) 25 public class FlutterShellArgs { 26 public static final String ARG_KEY_TRACE_STARTUP = "trace-startup"; 27 public static final String ARG_TRACE_STARTUP = "--trace-startup"; 28 public static final String ARG_KEY_START_PAUSED = "start-paused"; 29 public static final String ARG_START_PAUSED = "--start-paused"; 30 public static final String ARG_KEY_DISABLE_SERVICE_AUTH_CODES = "disable-service-auth-codes"; 31 public static final String ARG_DISABLE_SERVICE_AUTH_CODES = "--disable-service-auth-codes"; 32 public static final String ARG_KEY_USE_TEST_FONTS = "use-test-fonts"; 33 public static final String ARG_USE_TEST_FONTS = "--use-test-fonts"; 34 public static final String ARG_KEY_ENABLE_DART_PROFILING = "enable-dart-profiling"; 35 public static final String ARG_ENABLE_DART_PROFILING = "--enable-dart-profiling"; 36 public static final String ARG_KEY_ENABLE_SOFTWARE_RENDERING = "enable-software-rendering"; 37 public static final String ARG_ENABLE_SOFTWARE_RENDERING = "--enable-software-rendering"; 38 public static final String ARG_KEY_SKIA_DETERMINISTIC_RENDERING = "skia-deterministic-rendering"; 39 public static final String ARG_SKIA_DETERMINISTIC_RENDERING = "--skia-deterministic-rendering"; 40 public static final String ARG_KEY_TRACE_SKIA = "trace-skia"; 41 public static final String ARG_TRACE_SKIA = "--trace-skia"; 42 public static final String ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = "dump-skp-on-shader-compilation"; 43 public static final String ARG_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = "--dump-skp-on-shader-compilation"; 44 public static final String ARG_KEY_VERBOSE_LOGGING = "verbose-logging"; 45 public static final String ARG_VERBOSE_LOGGING = "--verbose-logging"; 46 public static final String ARG_KEY_OBSERVATORY_PORT = "observatory-port"; 47 public static final String ARG_OBSERVATORY_PORT = "--observatory-port="; 48 49 @NonNull fromIntent(@onNull Intent intent)50 public static FlutterShellArgs fromIntent(@NonNull Intent intent) { 51 // Before adding more entries to this list, consider that arbitrary 52 // Android applications can generate intents with extra data and that 53 // there are many security-sensitive args in the binary. 54 // TODO(mattcarroll): I left this warning as-is, but we should clarify what exactly this warning is warning against. 55 ArrayList<String> args = new ArrayList<>(); 56 57 if (intent.getBooleanExtra(ARG_KEY_TRACE_STARTUP, false)) { 58 args.add(ARG_TRACE_STARTUP); 59 } 60 if (intent.getBooleanExtra(ARG_KEY_START_PAUSED, false)) { 61 args.add(ARG_START_PAUSED); 62 } 63 final int observatoryPort = intent.getIntExtra(ARG_KEY_OBSERVATORY_PORT, 0); 64 if (observatoryPort > 0) { 65 args.add(ARG_OBSERVATORY_PORT + Integer.toString(observatoryPort)); 66 } 67 if (intent.getBooleanExtra(ARG_KEY_DISABLE_SERVICE_AUTH_CODES, false)) { 68 args.add(ARG_DISABLE_SERVICE_AUTH_CODES); 69 } 70 if (intent.getBooleanExtra(ARG_KEY_USE_TEST_FONTS, false)) { 71 args.add(ARG_USE_TEST_FONTS); 72 } 73 if (intent.getBooleanExtra(ARG_KEY_ENABLE_DART_PROFILING, false)) { 74 args.add(ARG_ENABLE_DART_PROFILING); 75 } 76 if (intent.getBooleanExtra(ARG_KEY_ENABLE_SOFTWARE_RENDERING, false)) { 77 args.add(ARG_ENABLE_SOFTWARE_RENDERING); 78 } 79 if (intent.getBooleanExtra(ARG_KEY_SKIA_DETERMINISTIC_RENDERING, false)) { 80 args.add(ARG_SKIA_DETERMINISTIC_RENDERING); 81 } 82 if (intent.getBooleanExtra(ARG_KEY_TRACE_SKIA, false)) { 83 args.add(ARG_TRACE_SKIA); 84 } 85 if (intent.getBooleanExtra(ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION, false)) { 86 args.add(ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION); 87 } 88 if (intent.getBooleanExtra(ARG_KEY_VERBOSE_LOGGING, false)) { 89 args.add(ARG_VERBOSE_LOGGING); 90 } 91 92 return new FlutterShellArgs(args); 93 } 94 95 @NonNull 96 private Set<String> args; 97 98 /** 99 * Creates a set of Flutter shell arguments from a given {@code String[]} array. 100 * The given arguments are automatically de-duplicated. 101 */ FlutterShellArgs(@onNull String[] args)102 public FlutterShellArgs(@NonNull String[] args) { 103 this.args = new HashSet<>(Arrays.asList(args)); 104 } 105 106 /** 107 * Creates a set of Flutter shell arguments from a given {@code List<String>}. 108 * The given arguments are automatically de-duplicated. 109 */ FlutterShellArgs(@onNull List<String> args)110 public FlutterShellArgs(@NonNull List<String> args) { 111 this.args = new HashSet<>(args); 112 } 113 114 /** 115 * Creates a set of Flutter shell arguments from a given {@code Set<String>}. 116 */ FlutterShellArgs(@onNull Set<String> args)117 public FlutterShellArgs(@NonNull Set<String> args) { 118 this.args = new HashSet<>(args); 119 } 120 121 /** 122 * Adds the given {@code arg} to this set of arguments. 123 * @param arg argument to add 124 */ add(@onNull String arg)125 public void add(@NonNull String arg) { 126 args.add(arg); 127 } 128 129 /** 130 * Removes the given {@code arg} from this set of arguments. 131 * @param arg argument to remove 132 */ remove(@onNull String arg)133 public void remove(@NonNull String arg) { 134 args.remove(arg); 135 } 136 137 /** 138 * Returns a new {@code String[]} array which contains each of the arguments 139 * within this {@code FlutterShellArgs}. 140 * 141 * @return array of arguments 142 */ 143 @NonNull toArray()144 public String[] toArray() { 145 String[] argsArray = new String[args.size()]; 146 return args.toArray(argsArray); 147 } 148 } 149