Camera2: Cache method list in MethodNameInvoker.

Retrieving list of methods in every invoke() call is very expensive.
Caching the list inside the constructor prevents several unnecessary
calls to Class.getMethods().

Test: Run camera2 CTS
Bug: 62490715

Change-Id: Ib2a93af0f364b055df2eab9bd7870730428429ad
diff --git a/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
index c66a3a4..8296b7a 100644
--- a/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
+++ b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
@@ -15,13 +15,13 @@
  */
 package android.hardware.camera2.dispatch;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
+
 import android.hardware.camera2.utils.UncheckedThrow;
 
 import java.lang.reflect.Method;
 import java.util.concurrent.ConcurrentHashMap;
 
-import static com.android.internal.util.Preconditions.*;
-
 /**
  * Invoke a method on a dispatchable by its name (without knowing the {@code Method} ahead of time).
  *
@@ -31,6 +31,7 @@
 
     private final Dispatchable<T> mTarget;
     private final Class<T> mTargetClass;
+    private final Method[] mTargetClassMethods;
     private final ConcurrentHashMap<String, Method> mMethods =
             new ConcurrentHashMap<>();
 
@@ -42,6 +43,7 @@
      */
     public MethodNameInvoker(Dispatchable<T> target, Class<T> targetClass) {
         mTargetClass = targetClass;
+        mTargetClassMethods = targetClass.getMethods();
         mTarget = target;
     }
 
@@ -68,7 +70,7 @@
 
         Method targetMethod = mMethods.get(methodName);
         if (targetMethod == null) {
-            for (Method method : mTargetClass.getMethods()) {
+            for (Method method : mTargetClassMethods) {
                 // TODO future: match types of params if possible
                 if (method.getName().equals(methodName) &&
                         (params.length == method.getParameterTypes().length) ) {