[flutter_plugin_android_lifecycle] Stop reflecting (#2467)

The reflection was added to make the plugin compatible with previous
versions of Flutter. Now that the latest stable has updated we can
update the code to be safer and avoid potential issues with code
shrinking in release builds.

Also removes a Gradle workaround that was only required for pre 1.12
versions of Flutter.
diff --git a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md
index eb4ac59..5ee91c8 100644
--- a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md
+++ b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.0.4
+
+* Require Flutter SDK 1.12.13 or greater.
+* Change to avoid reflection.
+
 ## 1.0.3
 
 * Remove the deprecated `author:` field from pubspec.yaml
diff --git a/packages/flutter_plugin_android_lifecycle/android/build.gradle b/packages/flutter_plugin_android_lifecycle/android/build.gradle
index 71b5ee2..77c8415 100644
--- a/packages/flutter_plugin_android_lifecycle/android/build.gradle
+++ b/packages/flutter_plugin_android_lifecycle/android/build.gradle
@@ -37,27 +37,8 @@
     }
 }
 
-// TODO(amirh): Remove this hack once androidx.lifecycle is included on stable. https://github.com/flutter/flutter/issues/42348
-afterEvaluate {
-    def containsEmbeddingDependencies = false
-    for (def configuration : configurations.all) {
-        for (def dependency : configuration.dependencies) {
-            if (dependency.group == 'io.flutter' &&
-                    dependency.name.startsWith('flutter_embedding') &&
-                    dependency.isTransitive())
-            {
-                containsEmbeddingDependencies = true
-                break
-            }
-        }
-    }
-    if (!containsEmbeddingDependencies) {
-        android {
-            dependencies {
-                def lifecycle_version = "2.1.0"
-                api "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
-                api "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
-            }
-        }
-    }
+dependencies {
+    testImplementation 'junit:junit:4.12'
+    testImplementation 'org.mockito:mockito-core:1.10.19'
 }
+
diff --git a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java
index c55c35c..91ac6e0 100644
--- a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java
+++ b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java
@@ -5,12 +5,8 @@
 package io.flutter.embedding.engine.plugins.lifecycle;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.lifecycle.Lifecycle;
-import io.flutter.Log;
 import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 
 /** Provides a static method for extracting lifecycle objects from Flutter plugin bindings. */
 public class FlutterLifecycleAdapter {
@@ -22,48 +18,11 @@
    * <p>Returns null if the Flutter engine version does not include the lifecycle extraction code.
    * (this probably means the Flutter engine version is too old).
    */
-  @Nullable
+  @NonNull
   public static Lifecycle getActivityLifecycle(
       @NonNull ActivityPluginBinding activityPluginBinding) {
-    try {
-      Method getLifecycle = ActivityPluginBinding.class.getMethod("getLifecycle");
-      Object hiddenLifecycle = getLifecycle.invoke(activityPluginBinding);
-      return getHiddenLifecycle(hiddenLifecycle);
-    } catch (ClassNotFoundException
-        | NoSuchMethodException
-        | IllegalAccessException
-        | InvocationTargetException e) {
-      Log.w(
-          TAG,
-          "You are attempting to use Flutter plugins that are newer than your"
-              + " version of Flutter. Plugins may not work as expected.");
-    }
-    return null;
-  }
-
-  // TODO(amirh): add a getter for a Service lifecycle.
-  // https://github.com/flutter/flutter/issues/43741
-
-  /**
-   * Returns the lifecycle object for the given Flutter plugin binding.
-   *
-   * <p>Returns null if the Flutter engine version does not include the lifecycle extraction code.
-   * (this probably means the Flutter engine version is too old).
-   */
-  @NonNull
-  private static Lifecycle getHiddenLifecycle(@NonNull Object reference)
-      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
-          ClassNotFoundException {
-    Class hiddenLifecycleClass =
-        Class.forName("io.flutter.embedding.engine.plugins.lifecycle.HiddenLifecycleReference");
-
-    if (!reference.getClass().equals(hiddenLifecycleClass)) {
-      throw new IllegalArgumentException(
-          "The reference argument must be of type HiddenLifecycleReference. Was actually "
-              + reference);
-    }
-
-    Method getLifecycle = reference.getClass().getMethod("getLifecycle");
-    return (Lifecycle) getLifecycle.invoke(reference);
+    HiddenLifecycleReference reference =
+        (HiddenLifecycleReference) activityPluginBinding.getLifecycle();
+    return reference.getLifecycle();
   }
 }
diff --git a/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java b/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java
new file mode 100644
index 0000000..2a5a91d
--- /dev/null
+++ b/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java
@@ -0,0 +1,87 @@
+package io.flutter.embedding.engine.plugins.lifecycle;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.Activity;
+import androidx.annotation.NonNull;
+import androidx.lifecycle.Lifecycle;
+import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
+import io.flutter.plugin.common.PluginRegistry;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class FlutterLifecycleAdapterTest {
+  @Mock Lifecycle lifecycle;
+
+  @Before
+  public void setUp() {
+    MockitoAnnotations.initMocks(this);
+  }
+
+  @Test
+  public void getActivityLifecycle() {
+    TestActivityPluginBinding binding = new TestActivityPluginBinding(lifecycle);
+
+    Lifecycle parsedLifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding);
+
+    assertEquals(lifecycle, parsedLifecycle);
+  }
+
+  private static final class TestActivityPluginBinding implements ActivityPluginBinding {
+    private final Lifecycle lifecycle;
+
+    TestActivityPluginBinding(Lifecycle lifecycle) {
+      this.lifecycle = lifecycle;
+    }
+
+    @NonNull
+    public Object getLifecycle() {
+      return new HiddenLifecycleReference(lifecycle);
+    }
+
+    @Override
+    public Activity getActivity() {
+      return null;
+    }
+
+    @Override
+    public void addRequestPermissionsResultListener(
+        @NonNull PluginRegistry.RequestPermissionsResultListener listener) {}
+
+    @Override
+    public void removeRequestPermissionsResultListener(
+        @NonNull PluginRegistry.RequestPermissionsResultListener listener) {}
+
+    @Override
+    public void addActivityResultListener(
+        @NonNull PluginRegistry.ActivityResultListener listener) {}
+
+    @Override
+    public void removeActivityResultListener(
+        @NonNull PluginRegistry.ActivityResultListener listener) {}
+
+    @Override
+    public void addOnNewIntentListener(@NonNull PluginRegistry.NewIntentListener listener) {}
+
+    @Override
+    public void removeOnNewIntentListener(@NonNull PluginRegistry.NewIntentListener listener) {}
+
+    @Override
+    public void addOnUserLeaveHintListener(
+        @NonNull PluginRegistry.UserLeaveHintListener listener) {}
+
+    @Override
+    public void removeOnUserLeaveHintListener(
+        @NonNull PluginRegistry.UserLeaveHintListener listener) {}
+
+    @Override
+    public void addOnSaveStateListener(
+        @NonNull ActivityPluginBinding.OnSaveInstanceStateListener listener) {}
+
+    @Override
+    public void removeOnSaveStateListener(
+        @NonNull ActivityPluginBinding.OnSaveInstanceStateListener listener) {}
+  }
+}
diff --git a/packages/flutter_plugin_android_lifecycle/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/pubspec.yaml
index ac35d8c..cea31bf 100644
--- a/packages/flutter_plugin_android_lifecycle/pubspec.yaml
+++ b/packages/flutter_plugin_android_lifecycle/pubspec.yaml
@@ -1,11 +1,11 @@
 name: flutter_plugin_android_lifecycle
 description: Flutter plugin for accessing an Android Lifecycle within other plugins.
-version: 1.0.3
+version: 1.0.4
 homepage: https://github.com/flutter/plugins/tree/master/packages/flutter_plugin_android_lifecycle
 
 environment:
   sdk: ">=2.1.0 <3.0.0"
-  flutter: ">=1.10.0 <2.0.0"
+  flutter: ">=1.12.13 <2.0.0"
 
 dependencies:
   flutter: