Replace @UseMethodParam annotation with generator classes.

Change-Id: I839b4f520300b17e3ba22cf0ea62d2a03b376c5e
Reviewed-on: https://chromium-review.googlesource.com/760419
Reviewed-by: Yaron Friedman <yfriedman@chromium.org>
Reviewed-by: Richard Coles <torne@chromium.org>
Commit-Queue: Bernhard Bauer <bauerb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551007}

CrOS-Libchrome-Original-Commit: a6a54b3a2b90ff125fc7d9da2c151979ced46120
diff --git a/base/android/proguard/chromium_apk.flags b/base/android/proguard/chromium_apk.flags
index 7b4f75b..ac3d7f8 100644
--- a/base/android/proguard/chromium_apk.flags
+++ b/base/android/proguard/chromium_apk.flags
@@ -28,6 +28,10 @@
     public static **[] values();
 }
 
+# Keep classes implementing ParameterProvider -- these will be instantiated
+# via reflection.
+-keep class * implements org.chromium.base.test.params.ParameterProvider
+
 # Allows Proguard freedom in removing these log related calls. We ask for debug
 # and verbose logs to be stripped out in base.Log, so we are just ensuring we
 # get rid of all other debug/verbose logs.
diff --git a/base/test/android/javatests/src/org/chromium/base/test/params/MethodParamAnnotationRule.java b/base/test/android/javatests/src/org/chromium/base/test/params/MethodParamAnnotationRule.java
index 188cfa8..2986b96 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/params/MethodParamAnnotationRule.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/params/MethodParamAnnotationRule.java
@@ -21,8 +21,8 @@
  */
 public class MethodParamAnnotationRule extends MethodParamRule {
     @Override
-    protected Statement applyParameterAndValues(
-            final Statement base, Object target, String parameterName, List<Object> values) {
+    protected Statement applyParameterAndValues(final Statement base, Object target,
+            Class<? extends ParameterProvider> parameterProvider, List<Object> values) {
         final List<Method> beforeMethods = new ArrayList<>();
         final List<Method> afterMethods = new ArrayList<>();
         for (Method m : target.getClass().getDeclaredMethods()) {
@@ -31,13 +31,13 @@
 
             UseMethodParameterBefore beforeAnnotation =
                     m.getAnnotation(UseMethodParameterBefore.class);
-            if (beforeAnnotation != null && beforeAnnotation.value().equals(parameterName)) {
+            if (beforeAnnotation != null && beforeAnnotation.value().equals(parameterProvider)) {
                 beforeMethods.add(m);
             }
 
             UseMethodParameterAfter afterAnnotation =
                     m.getAnnotation(UseMethodParameterAfter.class);
-            if (afterAnnotation != null && afterAnnotation.value().equals(parameterName)) {
+            if (afterAnnotation != null && afterAnnotation.value().equals(parameterProvider)) {
                 afterMethods.add(m);
             }
         }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/params/MethodParamRule.java b/base/test/android/javatests/src/org/chromium/base/test/params/MethodParamRule.java
index 4e6a6a3..440831a 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/params/MethodParamRule.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/params/MethodParamRule.java
@@ -14,22 +14,22 @@
 
 /**
  * Abstract base class for rules that are applied to test methods using
- * {@link org.chromium.base.test.params.ParameterAnnotations.MethodParameter method parameters}.
+ * {@link org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter method parameters}.
  */
 public abstract class MethodParamRule implements MethodRule {
     @Override
     public Statement apply(final Statement base, FrameworkMethod method, Object target) {
-        UseMethodParameter useMethodParameter = method.getAnnotation(UseMethodParameter.class);
-        if (useMethodParameter == null) return base;
-        String parameterName = useMethodParameter.value();
+        UseMethodParameter useParameterProvider = method.getAnnotation(UseMethodParameter.class);
+        if (useParameterProvider == null) return base;
+        Class<? extends ParameterProvider> parameterProvider = useParameterProvider.value();
 
         if (!(method instanceof ParameterizedFrameworkMethod)) return base;
         ParameterSet parameters = ((ParameterizedFrameworkMethod) method).getParameterSet();
         List<Object> values = parameters.getValues();
 
-        return applyParameterAndValues(base, target, parameterName, values);
+        return applyParameterAndValues(base, target, parameterProvider, values);
     }
 
-    protected abstract Statement applyParameterAndValues(
-            final Statement base, Object target, String parameterName, List<Object> values);
+    protected abstract Statement applyParameterAndValues(final Statement base, Object target,
+            Class<? extends ParameterProvider> parameterProvider, List<Object> values);
 }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterAnnotations.java b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterAnnotations.java
index c0042de..7918369 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterAnnotations.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterAnnotations.java
@@ -14,44 +14,41 @@
  */
 public class ParameterAnnotations {
     /**
-     * Annotation for test methods to indicate associated List<ParameterSet>
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.METHOD)
-    public @interface UseMethodParameter {
-        String value();
-    }
-
-    /**
      * Annotation for test methods to indicate associated {@link ParameterProvider}.
      * Note: the class referred to must be public and have a public default constructor.
      */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.METHOD)
-    public @interface UseParameterProvider {
+    public @interface UseMethodParameter {
         Class<? extends ParameterProvider> value();
     }
 
     /**
      * Annotation for methods that should be called before running a test with method parameters.
-     * @see MethodParameter
+     *
+     * In order to use this, add a {@link MethodParamAnnotationRule} annotated with
+     * {@code @}{@link org.junit.Rule Rule} to your test class.
+     * @see ParameterProvider
      * @see UseMethodParameterAfter
      */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.METHOD)
     public @interface UseMethodParameterBefore {
-        String value();
+        Class<? extends ParameterProvider> value();
     }
 
     /**
      * Annotation for methods that should be called after running a test with method parameters.
-     * @see MethodParameter
+     *
+     * In order to use this, add a {@link MethodParamAnnotationRule} annotated with
+     * {@code @}{@link org.junit.Rule Rule} to your test class.
+     * @see ParameterProvider
      * @see UseMethodParameterBefore
      */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.METHOD)
     public @interface UseMethodParameterAfter {
-        String value();
+        Class<? extends ParameterProvider> value();
     }
 
     /**
@@ -62,15 +59,6 @@
     public @interface ClassParameter {}
 
     /**
-     * Annotation for static field of a `List<ParameterSet>` for certain test methods
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.FIELD)
-    public @interface MethodParameter {
-        String value();
-    }
-
-    /**
      * Annotation for static field of a `List<ParameterSet>` of TestRule
      */
     @Retention(RetentionPolicy.RUNTIME)
diff --git a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterProvider.java b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterProvider.java
index 0fbe5e9..9bf27bd 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterProvider.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterProvider.java
@@ -4,10 +4,8 @@
 
 package org.chromium.base.test.params;
 
-import java.util.List;
-
 /**
  * Generator to use generate arguments for parameterized test methods.
- * @see ParameterAnnotations.UseParameterProvider
+ * @see ParameterAnnotations.UseMethodParameter
  */
-public interface ParameterProvider { List<ParameterSet> getParameters(); }
+public interface ParameterProvider { Iterable<ParameterSet> getParameters(); }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterSet.java b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterSet.java
index b38fb40..1cdb576 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterSet.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterSet.java
@@ -99,6 +99,7 @@
     }
 
     int size() {
+        if (mValues == null) return 0;
         return mValues.size();
     }
 
diff --git a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunner.java b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunner.java
index f2e25f4..f8f6c5f 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunner.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunner.java
@@ -12,7 +12,7 @@
 import org.junit.runners.model.TestClass;
 
 import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
-import org.chromium.base.test.params.ParameterAnnotations.MethodParameter;
+import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
 import org.chromium.base.test.params.ParameterizedRunnerDelegateFactory.ParameterizedRunnerDelegateInstantiationException;
 
@@ -20,21 +20,16 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 
 /**
  * ParameterizedRunner generates a list of runners for each of class parameter set in a test class.
  *
  * ParameterizedRunner looks for {@code @ClassParameter} annotation in test class and
- * generates a list of ParameterizedRunnerDelegate runners for each ParameterSet. The class
- * runner also looks for {@code @MethodParameter} annotation, and creates a map that maps Strings
- * value(tag) to ParameterSet List.
+ * generates a list of ParameterizedRunnerDelegate runners for each ParameterSet.
  */
 public final class ParameterizedRunner extends Suite {
-    private static final String TAG = "ParameterizedRunner";
     private final List<Runner> mRunners;
 
     /**
@@ -97,10 +92,10 @@
 
     private void validateAtLeastOneParameterSetField() {
         if (getTestClass().getAnnotatedFields(ClassParameter.class).isEmpty()
-                && getTestClass().getAnnotatedFields(MethodParameter.class).isEmpty()) {
+                && getTestClass().getAnnotatedMethods(UseMethodParameter.class).isEmpty()) {
             throw new IllegalArgumentException(String.format(Locale.getDefault(),
-                    "%s has no field annotated with @ClassParameter or @MethodParameter field, "
-                            + "it should not use ParameterizedRunner",
+                    "%s has no field annotated with @ClassParameter or method annotated with"
+                            + "@UseMethodParameter; it should not use ParameterizedRunner",
                     getTestClass().getName()));
         }
     }
@@ -119,8 +114,8 @@
      *
      * For method parameter set: a single list method parameter sets is associated with
      * a string tag, an immutable map of string to parameter set list will be created and
-     * passed into factory for each runner delegate to create multiple tests. only one
-     * Runner will be created for a method that uses @MethodParameter, regardless of the
+     * passed into factory for each runner delegate to create multiple tests. Only one
+     * Runner will be created for a method that uses @UseMethodParameter, regardless of the
      * number of ParameterSets in the associated list.
      *
      * @return a list of runners
@@ -145,35 +140,19 @@
         Class<? extends ParameterizedRunnerDelegate> runnerDelegateClass =
                 getRunnerDelegateClass(testClass);
         ParameterizedRunnerDelegateFactory factory = new ParameterizedRunnerDelegateFactory();
-        Map<String, List<ParameterSet>> tagToMethodParameterSetList =
-                Collections.unmodifiableMap(generateMethodParameterMap(testClass));
         List<Runner> runnersForTestClass = new ArrayList<>();
         for (ParameterSet classParameterSet : classParameterSetList) {
             BlockJUnit4ClassRunner runner = (BlockJUnit4ClassRunner) factory.createRunner(
-                    testClass, classParameterSet, tagToMethodParameterSetList, runnerDelegateClass);
+                    testClass, classParameterSet, runnerDelegateClass);
             runnersForTestClass.add(runner);
         }
         return runnersForTestClass;
     }
 
     /**
-     * Returns a map between MethodParameter tags and corresponding ParameterSetLists.
-     */
-    static Map<String, List<ParameterSet>> generateMethodParameterMap(TestClass testClass)
-            throws IllegalAccessException {
-        Map<String, List<ParameterSet>> result = new HashMap<>();
-        for (FrameworkField field : testClass.getAnnotatedFields(MethodParameter.class)) {
-            List<ParameterSet> parameterSetList = getParameterSetList(field, testClass);
-            validateWidth(parameterSetList);
-            result.put(field.getAnnotation(MethodParameter.class).value(), parameterSetList);
-        }
-        return result;
-    }
-
-    /**
      * Return an unmodifiable list of ParameterSet through a FrameworkField
      */
-    static List<ParameterSet> getParameterSetList(FrameworkField field, TestClass testClass)
+    private static List<ParameterSet> getParameterSetList(FrameworkField field, TestClass testClass)
             throws IllegalAccessException {
         field.getField().setAccessible(true);
         if (!Modifier.isStatic(field.getField().getModifiers())) {
@@ -183,8 +162,8 @@
         }
         if (!(field.get(testClass.getJavaClass()) instanceof List)) {
             throw new IllegalArgumentException(String.format(Locale.getDefault(),
-                    "Fields with @ClassParameter or @MethodParameter annotations must be an"
-                            + " instance of List, this field %s in %s is not list",
+                    "Fields with @ClassParameter annotations must be an instance of List, "
+                            + "this field %s in %s is not list",
                     field.getName(), testClass.getName()));
         }
         @SuppressWarnings("unchecked") // checked above
@@ -192,9 +171,13 @@
         return Collections.unmodifiableList(result);
     }
 
-    static void validateWidth(List<ParameterSet> parameterSetList) {
+    static void validateWidth(Iterable<ParameterSet> parameterSetList) {
         int lastSize = -1;
         for (ParameterSet set : parameterSetList) {
+            if (set.size() == 0) {
+                throw new IllegalParameterArgumentException(
+                        "No parameter is added to method ParameterSet");
+            }
             if (lastSize == -1 || set.size() == lastSize) {
                 lastSize = set.size();
             } else {
@@ -220,7 +203,7 @@
     }
 
     static class IllegalParameterArgumentException extends IllegalArgumentException {
-        public IllegalParameterArgumentException(String msg) {
+        IllegalParameterArgumentException(String msg) {
             super(msg);
         }
     }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunnerDelegateFactory.java b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunnerDelegateFactory.java
index 6033fc2..e3054d7 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunnerDelegateFactory.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunnerDelegateFactory.java
@@ -4,22 +4,17 @@
 
 package org.chromium.base.test.params;
 
-import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.TestClass;
 
 import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
-import org.chromium.base.test.params.ParameterAnnotations.UseParameterProvider;
 import org.chromium.base.test.params.ParameterizedRunner.ParameterizedTestInstantiationException;
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 /**
  * Factory to generate delegate class runners for ParameterizedRunner
@@ -30,29 +25,24 @@
      *
      * @param testClass the TestClass object for current test class
      * @param classParameterSet A parameter set for test constructor arguments
-     * @param testMethodToParameterSetListMap maps annotation tag to list of parameter set
      * @param parameterizedRunnerDelegateClass the parameterized runner delegate class specified
      *                                         through {@code @UseRunnerDelegate}
      */
     <T extends ParameterizedRunnerDelegate> T createRunner(TestClass testClass,
             ParameterSet classParameterSet,
-            Map<String, List<ParameterSet>> testMethodToParameterSetListMap,
             Class<T> parameterizedRunnerDelegateClass)
             throws ParameterizedTestInstantiationException,
                    ParameterizedRunnerDelegateInstantiationException {
         String testMethodPostfix = classParameterSet == null ? null : classParameterSet.getName();
         List<FrameworkMethod> unmodifiableFrameworkMethodList =
-                generateUnmodifiableFrameworkMethodList(
-                        testClass, testMethodToParameterSetListMap, testMethodPostfix);
+                generateUnmodifiableFrameworkMethodList(testClass, testMethodPostfix);
         Object test = createTest(testClass, classParameterSet);
         ParameterizedRunnerDelegateCommon delegateCommon =
                 new ParameterizedRunnerDelegateCommon(test, unmodifiableFrameworkMethodList);
         try {
-            T runnerDelegate = parameterizedRunnerDelegateClass
-                                       .getDeclaredConstructor(
-                                               Class.class, ParameterizedRunnerDelegateCommon.class)
-                                       .newInstance(testClass.getJavaClass(), delegateCommon);
-            return runnerDelegate;
+            return parameterizedRunnerDelegateClass
+                    .getDeclaredConstructor(Class.class, ParameterizedRunnerDelegateCommon.class)
+                    .newInstance(testClass.getJavaClass(), delegateCommon);
         } catch (Exception e) {
             throw new ParameterizedRunnerDelegateInstantiationException(
                     parameterizedRunnerDelegateClass.toString(), e);
@@ -65,33 +55,18 @@
      *
      * @param testClass a {@code TestClass} that wraps around the actual java
      *            test class
-     * @param tagToParameterSetList A map of String tags to ParameterSetList
      * @param postFix a name postfix for each test
      * @return a list of ParameterizedFrameworkMethod
      */
-    static List<FrameworkMethod> generateUnmodifiableFrameworkMethodList(TestClass testClass,
-            Map<String, List<ParameterSet>> tagToParameterSetList, String postFix) {
-        // A Map that maps string tag X to a list of test framework methods that are
-        // annotated with @UseMethodParameter(X)
-        Map<String, List<FrameworkMethod>> tagToListOfFrameworkMethod = new HashMap<>();
-
+    static List<FrameworkMethod> generateUnmodifiableFrameworkMethodList(
+            TestClass testClass, String postFix) {
         // Represent the list of all ParameterizedFrameworkMethod in this test class
         List<FrameworkMethod> returnList = new ArrayList<>();
 
-        // Create tagToListOfFrameworkMethod
         for (FrameworkMethod method : testClass.getAnnotatedMethods(Test.class)) {
             if (method.getMethod().isAnnotationPresent(UseMethodParameter.class)) {
-                String currentGroup = method.getAnnotation(UseMethodParameter.class).value();
-                if (tagToListOfFrameworkMethod.get(currentGroup) == null) {
-                    List<FrameworkMethod> list = new ArrayList<>();
-                    list.add(method);
-                    tagToListOfFrameworkMethod.put(currentGroup, list);
-                } else {
-                    tagToListOfFrameworkMethod.get(currentGroup).add(method);
-                }
-            } else if (method.getMethod().isAnnotationPresent(UseParameterProvider.class)) {
-                List<ParameterSet> parameterSets =
-                        getParameters(method.getAnnotation(UseParameterProvider.class).value());
+                Iterable<ParameterSet> parameterSets =
+                        getParameters(method.getAnnotation(UseMethodParameter.class).value());
                 returnList.addAll(createParameterizedMethods(method, parameterSets, postFix));
             } else {
                 // If test method is not parameterized (does not have UseMethodParameter annotation)
@@ -99,22 +74,6 @@
             }
         }
 
-        Assert.assertArrayEquals(
-                "All parameters used by must be defined, and all defined parameters must be used.",
-                tagToParameterSetList.keySet().toArray(),
-                tagToListOfFrameworkMethod.keySet().toArray());
-
-        // Loop through each of the tags and create all the parameterized framework
-        // methods for every method parameter set in the method parameter set list
-        // annotated with that tag
-        for (Entry<String, List<ParameterSet>> entry : tagToParameterSetList.entrySet()) {
-            String tagString = entry.getKey();
-            List<ParameterSet> parameterSetList = entry.getValue();
-            for (FrameworkMethod method : tagToListOfFrameworkMethod.get(tagString)) {
-                returnList.addAll(createParameterizedMethods(method, parameterSetList, postFix));
-            }
-        }
-
         return Collections.unmodifiableList(returnList);
     }
 
@@ -153,7 +112,7 @@
         }
     }
 
-    private static List<ParameterSet> getParameters(Class<? extends ParameterProvider> clazz) {
+    private static Iterable<ParameterSet> getParameters(Class<? extends ParameterProvider> clazz) {
         ParameterProvider parameterProvider;
         try {
             parameterProvider = clazz.getDeclaredConstructor().newInstance();
@@ -170,12 +129,10 @@
     }
 
     private static List<FrameworkMethod> createParameterizedMethods(
-            FrameworkMethod baseMethod, List<ParameterSet> parameterSetList, String suffix) {
+            FrameworkMethod baseMethod, Iterable<ParameterSet> parameterSetList, String suffix) {
+        ParameterizedRunner.validateWidth(parameterSetList);
         List<FrameworkMethod> returnList = new ArrayList<>();
         for (ParameterSet set : parameterSetList) {
-            if (set.getValues() == null) {
-                throw new IllegalArgumentException("No parameter is added to method ParameterSet");
-            }
             returnList.add(new ParameterizedFrameworkMethod(baseMethod.getMethod(), set, suffix));
         }
         return returnList;
diff --git a/base/test/android/junit/src/org/chromium/base/test/params/ExampleParameterizedTest.java b/base/test/android/junit/src/org/chromium/base/test/params/ExampleParameterizedTest.java
index 1728bfb..6ffccad 100644
--- a/base/test/android/junit/src/org/chromium/base/test/params/ExampleParameterizedTest.java
+++ b/base/test/android/junit/src/org/chromium/base/test/params/ExampleParameterizedTest.java
@@ -4,9 +4,6 @@
 
 package org.chromium.base.test.params;
 
-import static org.chromium.base.test.params.ParameterAnnotations.MethodParameter;
-import static org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
-
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
@@ -14,16 +11,16 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
+import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameterAfter;
 import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameterBefore;
-import org.chromium.base.test.params.ParameterAnnotations.UseParameterProvider;
 import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
 
 import java.util.Arrays;
 import java.util.List;
 
 /**
- * Example test that uses ParamRunner
+ * Example test that uses ParameterizedRunner
  */
 @RunWith(ParameterizedRunner.class)
 @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
@@ -34,26 +31,31 @@
                     new ParameterSet().value("Xxxx", "Yyyy").name("XxxxYyyy"),
                     new ParameterSet().value("aa", "yy").name("AaYy"));
 
-    @MethodParameter("A")
-    private static List<ParameterSet> sMethodParamA =
-            Arrays.asList(new ParameterSet().value(1, 2).name("OneTwo"),
-                    new ParameterSet().value(2, 3).name("TwoThree"),
-                    new ParameterSet().value(3, 4).name("ThreeFour"));
-
-    @MethodParameter("B")
-    private static List<ParameterSet> sMethodParamB =
-            Arrays.asList(new ParameterSet().value("a", "b").name("Ab"),
-                    new ParameterSet().value("b", "c").name("Bc"),
-                    new ParameterSet().value("c", "d").name("Cd"),
-                    new ParameterSet().value("d", "e").name("De"));
-
     public static class MethodParamsA implements ParameterProvider {
+        private static List<ParameterSet> sMethodParamA =
+                Arrays.asList(new ParameterSet().value(1, 2).name("OneTwo"),
+                        new ParameterSet().value(2, 3).name("TwoThree"),
+                        new ParameterSet().value(3, 4).name("ThreeFour"));
+
         @Override
         public List<ParameterSet> getParameters() {
             return sMethodParamA;
         }
     }
 
+    public static class MethodParamsB implements ParameterProvider {
+        private static List<ParameterSet> sMethodParamB =
+                Arrays.asList(new ParameterSet().value("a", "b").name("Ab"),
+                        new ParameterSet().value("b", "c").name("Bc"),
+                        new ParameterSet().value("c", "d").name("Cd"),
+                        new ParameterSet().value("d", "e").name("De"));
+
+        @Override
+        public List<ParameterSet> getParameters() {
+            return sMethodParamB;
+        }
+    }
+
     private String mStringA;
     private String mStringB;
 
@@ -73,35 +75,29 @@
 
     private Integer mSum;
 
-    @UseMethodParameterBefore("A")
+    @UseMethodParameterBefore(MethodParamsA.class)
     public void setupWithOnlyA(int intA, int intB) {
         mSum = intA + intB;
     }
 
     @Test
-    @UseMethodParameter("A")
+    @UseMethodParameter(MethodParamsA.class)
     public void testWithOnlyA(int intA, int intB) {
         Assert.assertEquals(intA + 1, intB);
         Assert.assertEquals(mSum, Integer.valueOf(intA + intB));
         mSum = null;
     }
 
-    @Test
-    @UseParameterProvider(MethodParamsA.class)
-    public void testWithOnlyAFromGenerator(int intA, int intB) {
-        Assert.assertEquals(intA + 1, intB);
-    }
-
     private String mConcatenation;
 
     @Test
-    @UseMethodParameter("B")
+    @UseMethodParameter(MethodParamsB.class)
     public void testWithOnlyB(String a, String b) {
         Assert.assertTrue(!a.equals(b));
         mConcatenation = a + b;
     }
 
-    @UseMethodParameterAfter("B")
+    @UseMethodParameterAfter(MethodParamsB.class)
     public void teardownWithOnlyB(String a, String b) {
         Assert.assertEquals(mConcatenation, a + b);
         mConcatenation = null;
diff --git a/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedRunnerDelegateFactoryTest.java b/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedRunnerDelegateFactoryTest.java
index 3be81a9..6b62a95 100644
--- a/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedRunnerDelegateFactoryTest.java
+++ b/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedRunnerDelegateFactoryTest.java
@@ -17,8 +17,7 @@
 import org.chromium.base.test.params.ParameterizedRunnerDelegateFactory.ParameterizedRunnerDelegateInstantiationException;
 
 import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -72,13 +71,34 @@
     }
 
     static class ExampleTestClass {
+        static class MethodParamsA implements ParameterProvider {
+            @Override
+            public Iterable<ParameterSet> getParameters() {
+                return Arrays.asList(
+                        new ParameterSet().value("a").name("testWithValue_a"),
+                        new ParameterSet().value("b").name("testWithValue_b")
+                );
+            }
+        }
+
         @SuppressWarnings("unused")
-        @UseMethodParameter("A")
+        @UseMethodParameter(MethodParamsA.class)
         @Test
         public void testA(String a) {}
 
+        static class MethodParamsB implements ParameterProvider {
+            @Override
+            public Iterable<ParameterSet> getParameters() {
+                return Arrays.asList(
+                        new ParameterSet().value(1).name("testWithValue_1"),
+                        new ParameterSet().value(2).name("testWithValue_2"),
+                        new ParameterSet().value(3).name("testWithValue_3")
+                );
+            }
+        }
+
         @SuppressWarnings("unused")
-        @UseMethodParameter("B")
+        @UseMethodParameter(MethodParamsB.class)
         @Test
         public void testB(int b) {}
 
@@ -94,8 +114,7 @@
     public void testBadRunnerDelegateWithIncorrectValidationCall() throws Throwable {
         ParameterizedRunnerDelegateFactory factory = new ParameterizedRunnerDelegateFactory();
         TestClass testClass = new TestClass(BadExampleRunnerDelegate.LalaTestClass.class);
-        factory.createRunner(
-                testClass, null, Collections.emptyMap(), BadExampleRunnerDelegate.class);
+        factory.createRunner(testClass, null, BadExampleRunnerDelegate.class);
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -113,21 +132,9 @@
 
     @Test
     public void testGenerateParameterizedFrameworkMethod() throws Throwable {
-        Map<String, List<ParameterSet>> map = new HashMap<>();
-        List<ParameterSet> listA = new ArrayList<>();
-        listA.add(new ParameterSet().value("a").name("testWithValue_a"));
-        listA.add(new ParameterSet().value("b").name("testWithValue_b"));
-
-        List<ParameterSet> listB = new ArrayList<>();
-        listB.add(new ParameterSet().value(1).name("testWithValue_1"));
-        listB.add(new ParameterSet().value(2).name("testWithValue_2"));
-        listB.add(new ParameterSet().value(3).name("testWithValue_3"));
-        map.put("A", listA);
-        map.put("B", listB);
-
         List<FrameworkMethod> methods =
                 ParameterizedRunnerDelegateFactory.generateUnmodifiableFrameworkMethodList(
-                        new TestClass(ExampleTestClass.class), map, "");
+                        new TestClass(ExampleTestClass.class), "");
 
         Assert.assertEquals(methods.size(), 6);
 
@@ -148,44 +155,4 @@
         }
         Assert.assertTrue(expectedTests.isEmpty());
     }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testEmptyParameterSet() {
-        Map<String, List<ParameterSet>> map = new HashMap<>();
-        List<ParameterSet> listA = new ArrayList<>();
-        listA.add(new ParameterSet().value("a").name("testWithValue_a"));
-        List<ParameterSet> listB = new ArrayList<>();
-        listB.add(new ParameterSet()); //Empty parameter set
-        map.put("A", listA);
-        map.put("B", listB);
-        ParameterizedRunnerDelegateFactory.generateUnmodifiableFrameworkMethodList(
-                new TestClass(ExampleTestClass.class), map, "");
-    }
-
-    @Test(expected = AssertionError.class)
-    public void testMissingParameterSet() {
-        Map<String, List<ParameterSet>> map = new HashMap<>();
-        List<ParameterSet> listA = new ArrayList<>();
-        listA.add(new ParameterSet().value("a").name("testWithValue_a"));
-        map.put("A", listA);
-        //Missing ParameterSet list under group "B"
-        ParameterizedRunnerDelegateFactory.generateUnmodifiableFrameworkMethodList(
-                new TestClass(ExampleTestClass.class), map, "");
-    }
-
-    @Test(expected = AssertionError.class)
-    public void testMissingTestMethod() {
-        Map<String, List<ParameterSet>> map = new HashMap<>();
-        List<ParameterSet> listA = new ArrayList<>();
-        listA.add(new ParameterSet().value("a").name("testWithValue_a"));
-        List<ParameterSet> listB = new ArrayList<>();
-        listB.add(new ParameterSet().value(1).name("testWithValue_1"));
-        List<ParameterSet> listC = new ArrayList<>();
-        listC.add(new ParameterSet().value(10).name("extra"));
-        map.put("A", listA);
-        map.put("B", listB);
-        map.put("C", listC);
-        ParameterizedRunnerDelegateFactory.generateUnmodifiableFrameworkMethodList(
-                new TestClass(ExampleTestClass.class), map, "");
-    }
 }
diff --git a/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedRunnerTest.java b/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedRunnerTest.java
index 40978a7..170ff69 100644
--- a/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedRunnerTest.java
+++ b/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedRunnerTest.java
@@ -4,22 +4,16 @@
 
 package org.chromium.base.test.params;
 
-import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runner.Runner;
 import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.TestClass;
 
 import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
-import org.chromium.base.test.params.ParameterAnnotations.MethodParameter;
-import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
 import org.chromium.base.test.params.ParameterizedRunner.IllegalParameterArgumentException;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Test for org.chromium.base.test.params.ParameterizedRunner
@@ -27,53 +21,6 @@
 @RunWith(BlockJUnit4ClassRunner.class)
 public class ParameterizedRunnerTest {
     @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
-    public static class TestClassWithPrivateParameterSetList {
-        @ClassParameter
-        private static List<ParameterSet> sClassParams = new ArrayList<>();
-
-        static {
-            sClassParams.add(new ParameterSet().value(1));
-            sClassParams.add(new ParameterSet().value(2));
-        }
-
-        @MethodParameter("A")
-        private static List<ParameterSet> sMethodParamA = new ArrayList<>();
-
-        static {
-            sMethodParamA.add(new ParameterSet().value("a", "b"));
-        }
-
-        public TestClassWithPrivateParameterSetList(int x) {}
-
-        @Test
-        @UseMethodParameter("A")
-        public void test(String a, String b) {}
-    }
-
-    @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
-    public static class TestClassWithDefaultParameterSetList {
-        @ClassParameter
-        static List<ParameterSet> sClassParams = new ArrayList<>();
-
-        static {
-            sClassParams.add(new ParameterSet().value(1, 2));
-        }
-
-        @MethodParameter("A")
-        static List<ParameterSet> sMethodParamA = new ArrayList<>();
-
-        static {
-            sMethodParamA.add(new ParameterSet().value(null));
-        }
-
-        public TestClassWithDefaultParameterSetList(int a, int b) {}
-
-        @Test
-        @UseMethodParameter("A")
-        public void test(String x) {}
-    }
-
-    @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
     public static class BadTestClassWithMoreThanOneConstructor {
         @ClassParameter
         static List<ParameterSet> sClassParams = new ArrayList<>();
@@ -101,26 +48,13 @@
     @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
     public static class BadTestClassWithNonStaticParameterSetList {
         @ClassParameter
-        public List<ParameterSet> sClassParams = new ArrayList<>();
+        public List<ParameterSet> mClassParams = new ArrayList<>();
 
         @Test
         public void test() {}
     }
 
     @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
-    public static class BadTestClassWithMissingMethodParameter {
-        @MethodParameter("A")
-        private static List<ParameterSet> sParameterSetListA = new ArrayList<>();
-
-        @MethodParameter("B")
-        private static List<ParameterSet> sParameterSetListB = new ArrayList<>();
-
-        @Test
-        @UseMethodParameter("A")
-        public void testA() {}
-    }
-
-    @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
     public static class BadTestClassWithMultipleClassParameter {
         @ClassParameter
         private static List<ParameterSet> sParamA = new ArrayList<>();
@@ -129,28 +63,11 @@
         private static List<ParameterSet> sParamB = new ArrayList<>();
     }
 
-    @Test
-    public void testPrivateAccessible() throws Throwable {
-        TestClass testClass = new TestClass(TestClassWithPrivateParameterSetList.class);
-        List<Runner> runners = ParameterizedRunner.createRunners(testClass);
-        Assert.assertEquals(runners.size(), 2);
-        Map<String, List<ParameterSet>> generatedMap =
-                ParameterizedRunner.generateMethodParameterMap(testClass);
-        Assert.assertEquals(generatedMap.keySet().size(), 1);
-        Assert.assertTrue(generatedMap.keySet().contains("A"));
-        Assert.assertEquals(generatedMap.get("A").size(), 1);
-    }
-
-    @Test
-    public void testDefaultAccessible() throws Throwable {
-        TestClass testClass = new TestClass(TestClassWithDefaultParameterSetList.class);
-        List<Runner> runners = ParameterizedRunner.createRunners(testClass);
-        Assert.assertEquals(runners.size(), 1);
-        Map<String, List<ParameterSet>> generatedMap =
-                ParameterizedRunner.generateMethodParameterMap(testClass);
-        Assert.assertEquals(generatedMap.keySet().size(), 1);
-        Assert.assertTrue(generatedMap.keySet().contains("A"));
-        Assert.assertEquals(generatedMap.get("A").size(), 1);
+    @Test(expected = ParameterizedRunner.IllegalParameterArgumentException.class)
+    public void testEmptyParameterSet() {
+        List<ParameterSet> paramList = new ArrayList<>();
+        paramList.add(new ParameterSet());
+        ParameterizedRunner.validateWidth(paramList);
     }
 
     @Test(expected = ParameterizedRunner.IllegalParameterArgumentException.class)
@@ -171,31 +88,21 @@
 
     @Test(expected = IllegalArgumentException.class)
     public void testBadClassWithNonListParameters() throws Throwable {
-        ParameterizedRunner runner =
-                new ParameterizedRunner(BadTestClassWithNonListParameters.class);
+        new ParameterizedRunner(BadTestClassWithNonListParameters.class);
     }
 
     @Test(expected = IllegalParameterArgumentException.class)
     public void testBadClassWithNonStaticParameterSetList() throws Throwable {
-        ParameterizedRunner runner =
-                new ParameterizedRunner(BadTestClassWithNonStaticParameterSetList.class);
-    }
-
-    @Test(expected = AssertionError.class)
-    public void testBadClassWithMissingMethodParameter() throws Throwable {
-        ParameterizedRunner runner =
-                new ParameterizedRunner(BadTestClassWithMissingMethodParameter.class);
+        new ParameterizedRunner(BadTestClassWithNonStaticParameterSetList.class);
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void testBadClassWithoutNeedForParameterization() throws Throwable {
-        ParameterizedRunner runner =
-                new ParameterizedRunner(BadTestClassWithoutNeedForParameterization.class);
+        new ParameterizedRunner(BadTestClassWithoutNeedForParameterization.class);
     }
 
     @Test(expected = Exception.class)
     public void testBadClassWithMoreThanOneConstructor() throws Throwable {
-        ParameterizedRunner runner =
-                new ParameterizedRunner(BadTestClassWithMoreThanOneConstructor.class);
+        new ParameterizedRunner(BadTestClassWithMoreThanOneConstructor.class);
     }
 }
diff --git a/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedTestNameTest.java b/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedTestNameTest.java
index 7072757..e79f5c5 100644
--- a/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedTestNameTest.java
+++ b/base/test/android/junit/src/org/chromium/base/test/params/ParameterizedTestNameTest.java
@@ -13,7 +13,6 @@
 import org.junit.runners.model.TestClass;
 
 import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
-import org.chromium.base.test.params.ParameterAnnotations.MethodParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
 
@@ -30,11 +29,10 @@
     @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
     public static class TestClassWithClassParameterAppendName {
         @ClassParameter
-        static List<ParameterSet> sAllName = new ArrayList<>();
-        static {
-            sAllName.add(new ParameterSet().value("hello").name("Hello"));
-            sAllName.add(new ParameterSet().value("world").name("World"));
-        }
+        static List<ParameterSet> sAllName = Arrays.asList(
+                new ParameterSet().value("hello").name("Hello"),
+                new ParameterSet().value("world").name("World")
+        );
 
         public TestClassWithClassParameterAppendName(String a) {}
 
@@ -45,11 +43,10 @@
     @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
     public static class TestClassWithClassParameterDefaultName {
         @ClassParameter
-        static List<ParameterSet> sAllName = new ArrayList<>();
-        static {
-            sAllName.add(new ParameterSet().value("hello"));
-            sAllName.add(new ParameterSet().value("world"));
-        }
+        static List<ParameterSet> sAllName = Arrays.asList(
+                new ParameterSet().value("hello"),
+                new ParameterSet().value("world")
+        );
 
         public TestClassWithClassParameterDefaultName(String a) {}
 
@@ -59,25 +56,31 @@
 
     @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
     public static class TestClassWithMethodParameter {
-        @MethodParameter("A")
-        static List<ParameterSet> sAppendName = new ArrayList<>();
-        static {
-            sAppendName.add(new ParameterSet().value("hello").name("Hello"));
-            sAppendName.add(new ParameterSet().value("world").name("World"));
+        static class AppendNameParams implements ParameterProvider {
+            @Override
+            public Iterable<ParameterSet> getParameters() {
+                return Arrays.asList(
+                        new ParameterSet().value("hello").name("Hello"),
+                        new ParameterSet().value("world").name("World")
+                );
+            }
         }
 
-        @MethodParameter("B")
-        static List<ParameterSet> sDefaultName = new ArrayList<>();
-        static {
-            sDefaultName.add(new ParameterSet().value("hello"));
-            sDefaultName.add(new ParameterSet().value("world"));
+        static class DefaultNameParams implements ParameterProvider {
+            @Override
+            public Iterable<ParameterSet> getParameters() {
+                return Arrays.asList(
+                        new ParameterSet().value("hello"),
+                        new ParameterSet().value("world")
+                );
+            }
         }
 
-        @UseMethodParameter("A")
+        @UseMethodParameter(AppendNameParams.class)
         @Test
         public void test(String a) {}
 
-        @UseMethodParameter("B")
+        @UseMethodParameter(DefaultNameParams.class)
         @Test
         public void testDefaultName(String b) {}
     }
@@ -85,22 +88,24 @@
     @UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
     public static class TestClassWithMixedParameter {
         @ClassParameter
-        static List<ParameterSet> sAllName = new ArrayList<>();
-        static {
-            sAllName.add(new ParameterSet().value("hello").name("Hello"));
-            sAllName.add(new ParameterSet().value("world").name("World"));
-        }
+        static List<ParameterSet> sAllName = Arrays.asList(
+                new ParameterSet().value("hello").name("Hello"),
+                new ParameterSet().value("world").name("World")
+        );
 
-        @MethodParameter("A")
-        static List<ParameterSet> sAppendName = new ArrayList<>();
-        static {
-            sAppendName.add(new ParameterSet().value("1").name("A"));
-            sAppendName.add(new ParameterSet().value("2").name("B"));
+        static class AppendNameParams implements ParameterProvider {
+            @Override
+            public Iterable<ParameterSet> getParameters() {
+                return Arrays.asList(
+                        new ParameterSet().value("1").name("A"),
+                        new ParameterSet().value("2").name("B")
+                );
+            }
         }
 
         public TestClassWithMixedParameter(String a) {}
 
-        @UseMethodParameter("A")
+        @UseMethodParameter(AppendNameParams.class)
         @Test
         public void testA(String a) {}
 
@@ -113,7 +118,7 @@
         List<Runner> runners = ParameterizedRunner.createRunners(
                 new TestClass(TestClassWithClassParameterAppendName.class));
         List<String> expectedTestNames =
-                new LinkedList<String>(Arrays.asList(new String[] {"test__Hello", "test__World"}));
+                new LinkedList<String>(Arrays.asList("test__Hello", "test__World"));
         List<String> computedMethodNames = new ArrayList<>();
         for (Runner r : runners) {
             BlockJUnit4RunnerDelegate castedRunner = (BlockJUnit4RunnerDelegate) r;
@@ -137,8 +142,7 @@
     public void testClassParameterDefaultName() throws Throwable {
         List<Runner> runners = ParameterizedRunner.createRunners(
                 new TestClass(TestClassWithClassParameterDefaultName.class));
-        List<String> expectedTestNames =
-                new LinkedList<String>(Arrays.asList(new String[] {"test", "test"}));
+        List<String> expectedTestNames = new LinkedList<String>(Arrays.asList("test", "test"));
         for (Runner r : runners) {
             @SuppressWarnings("unchecked")
             BlockJUnit4RunnerDelegate castedRunner = (BlockJUnit4RunnerDelegate) r;
@@ -158,8 +162,8 @@
     public void testMethodParameter() throws Throwable {
         List<Runner> runners = ParameterizedRunner.createRunners(
                 new TestClass(TestClassWithMethodParameter.class));
-        List<String> expectedTestNames = new LinkedList<String>(Arrays.asList(
-                new String[] {"test__Hello", "test__World", "testDefaultName", "testDefaultName"}));
+        List<String> expectedTestNames = new LinkedList<String>(
+                Arrays.asList("test__Hello", "test__World", "testDefaultName", "testDefaultName"));
         for (Runner r : runners) {
             BlockJUnit4RunnerDelegate castedRunner = (BlockJUnit4RunnerDelegate) r;
             for (FrameworkMethod method : castedRunner.computeTestMethods()) {
@@ -178,9 +182,9 @@
     public void testMixedParameterTestA() throws Throwable {
         List<Runner> runners =
                 ParameterizedRunner.createRunners(new TestClass(TestClassWithMixedParameter.class));
-        List<String> expectedTestNames = new LinkedList<String>(
-                Arrays.asList(new String[] {"testA__Hello_A", "testA__World_A", "testA__Hello_B",
-                        "testA__World_B", "test__Hello", "test__World"}));
+        List<String> expectedTestNames =
+                new LinkedList<String>(Arrays.asList("testA__Hello_A", "testA__World_A",
+                        "testA__Hello_B", "testA__World_B", "test__Hello", "test__World"));
         for (Runner r : runners) {
             BlockJUnit4RunnerDelegate castedRunner = (BlockJUnit4RunnerDelegate) r;
             for (FrameworkMethod method : castedRunner.computeTestMethods()) {