| // 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; | |
| import android.support.annotation.NonNull; | |
| import android.support.annotation.VisibleForTesting; | |
| import io.flutter.embedding.engine.loader.FlutterLoader; | |
| /** | |
| * This class is a simple dependency injector for the relatively thin Android part of the Flutter | |
| * engine. | |
| * | |
| * <p>This simple solution is used facilitate testability without bringing in heavier | |
| * app-development centric dependency injection frameworks such as Guice or Dagger2 or spreading | |
| * construction injection everywhere. | |
| */ | |
| public final class FlutterInjector { | |
| private static FlutterInjector instance; | |
| private static boolean accessed; | |
| /** | |
| * Use {@link FlutterInjector.Builder} to specify members to be injected via the static {@code | |
| * FlutterInjector}. | |
| * | |
| * <p>This can only be called at the beginning of the program before the {@link #instance()} is | |
| * accessed. | |
| */ | |
| @VisibleForTesting | |
| public static void setInstance(@NonNull FlutterInjector injector) { | |
| if (accessed) { | |
| throw new IllegalStateException( | |
| "Cannot change the FlutterInjector instance once it's been " | |
| + "read. If you're trying to dependency inject, be sure to do so at the beginning of " | |
| + "the program"); | |
| } | |
| instance = injector; | |
| } | |
| /** | |
| * Retrieve the static instance of the {@code FlutterInjector} to use in your program. | |
| * | |
| * <p>Once you access it, you can no longer change the values injected. | |
| * | |
| * <p>If no override is provided for the injector, reasonable defaults are provided. | |
| */ | |
| public static FlutterInjector instance() { | |
| accessed = true; | |
| if (instance == null) { | |
| instance = new Builder().build(); | |
| } | |
| return instance; | |
| } | |
| // This whole class is here to enable testing so to test the thing that lets you test, some degree | |
| // of hack is needed. | |
| @VisibleForTesting | |
| public static void reset() { | |
| accessed = false; | |
| instance = null; | |
| } | |
| private FlutterInjector(boolean shouldLoadNative, @NonNull FlutterLoader flutterLoader) { | |
| this.shouldLoadNative = shouldLoadNative; | |
| this.flutterLoader = flutterLoader; | |
| } | |
| private boolean shouldLoadNative; | |
| private FlutterLoader flutterLoader; | |
| /** | |
| * Returns whether the Flutter Android engine embedding should load the native C++ engine. | |
| * | |
| * <p>Useful for testing since JVM tests via Robolectric can't load native libraries. | |
| */ | |
| public boolean shouldLoadNative() { | |
| return shouldLoadNative; | |
| } | |
| /** Returns the {@link FlutterLoader} instance to use for the Flutter Android engine embedding. */ | |
| @NonNull | |
| public FlutterLoader flutterLoader() { | |
| return flutterLoader; | |
| } | |
| /** | |
| * Builder used to supply a custom FlutterInjector instance to {@link | |
| * FlutterInjector#setInstance(FlutterInjector)}. | |
| * | |
| * <p>Non-overriden values have reasonable defaults. | |
| */ | |
| public static final class Builder { | |
| private boolean shouldLoadNative = true; | |
| /** | |
| * Sets whether the Flutter Android engine embedding should load the native C++ engine. | |
| * | |
| * <p>Useful for testing since JVM tests via Robolectric can't load native libraries. | |
| * | |
| * <p>Defaults to true. | |
| */ | |
| public Builder setShouldLoadNative(boolean shouldLoadNative) { | |
| this.shouldLoadNative = shouldLoadNative; | |
| return this; | |
| } | |
| private FlutterLoader flutterLoader; | |
| /** | |
| * Sets a {@link FlutterLoader} override. | |
| * | |
| * <p>A reasonable default will be used if unspecified. | |
| */ | |
| public Builder setFlutterLoader(@NonNull FlutterLoader flutterLoader) { | |
| this.flutterLoader = flutterLoader; | |
| return this; | |
| } | |
| private void fillDefaults() { | |
| if (flutterLoader == null) { | |
| flutterLoader = new FlutterLoader(); | |
| } | |
| } | |
| /** | |
| * Builds a {@link FlutterInjector} from the builder. Unspecified properties will have | |
| * reasonable defaults. | |
| */ | |
| public FlutterInjector build() { | |
| fillDefaults(); | |
| System.out.println("should load native is " + shouldLoadNative); | |
| return new FlutterInjector(shouldLoadNative, flutterLoader); | |
| } | |
| } | |
| } |