diff options
author | jbudorick <jbudorick@chromium.org> | 2015-02-02 18:17:45 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-03 02:18:45 +0000 |
commit | d19a57db9b237b197c5910f39ccbf53538ccf92d (patch) | |
tree | e7f32ae9840ceefb213dff9851d57948044d0c61 /base | |
parent | 31bc0e862f93d2d020e2d0eb3b47e2b252e05ff8 (diff) | |
download | chromium_src-d19a57db9b237b197c5910f39ccbf53538ccf92d.zip chromium_src-d19a57db9b237b197c5910f39ccbf53538ccf92d.tar.gz chromium_src-d19a57db9b237b197c5910f39ccbf53538ccf92d.tar.bz2 |
[Android] Add support for command-line flags via annotation.
BUG=433539
Review URL: https://codereview.chromium.org/879993002
Cr-Commit-Position: refs/heads/master@{#314247}
Diffstat (limited to 'base')
4 files changed, 182 insertions, 0 deletions
diff --git a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java index a9dc2f7..8f7d39d 100644 --- a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java +++ b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java @@ -6,6 +6,7 @@ package org.chromium.base; import android.app.Activity; import android.app.Application; +import android.content.Context; import android.os.Bundle; import android.view.Window; @@ -96,4 +97,16 @@ public class BaseChromiumApplication extends Application { public void unregisterWindowFocusChangedListener(WindowFocusChangedListener listener) { mWindowFocusListeners.removeObserver(listener); } + + /** Initializes the {@link CommandLine}. */ + public void initCommandLine() {} + + /** + * This must only be called for contexts whose application is a subclass of + * {@link BaseChromiumApplication}. + */ + @VisibleForTesting + public static void initCommandLine(Context context) { + ((BaseChromiumApplication) context.getApplicationContext()).initCommandLine(); + }; } diff --git a/base/android/java/src/org/chromium/base/CommandLine.java b/base/android/java/src/org/chromium/base/CommandLine.java index 406f36b..43e0004 100644 --- a/base/android/java/src/org/chromium/base/CommandLine.java +++ b/base/android/java/src/org/chromium/base/CommandLine.java @@ -31,6 +31,7 @@ public abstract class CommandLine { * Returns true if this command line contains the given switch. * (Switch names ARE case-sensitive). */ + @VisibleForTesting public abstract boolean hasSwitch(String switchString); /** @@ -57,6 +58,7 @@ public abstract class CommandLine { * this action happens before the switch is needed. * @param switchString the switch to add. It should NOT start with '--' ! */ + @VisibleForTesting public abstract void appendSwitch(String switchString); /** @@ -96,6 +98,7 @@ public abstract class CommandLine { } // Equivalent to CommandLine::ForCurrentProcess in C++. + @VisibleForTesting public static CommandLine getInstance() { CommandLine commandLine = sCommandLine.get(); assert commandLine != null; diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseActivityInstrumentationTestCase.java b/base/test/android/javatests/src/org/chromium/base/test/BaseActivityInstrumentationTestCase.java new file mode 100644 index 0000000..53dee4a --- /dev/null +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseActivityInstrumentationTestCase.java @@ -0,0 +1,118 @@ +// Copyright 2015 The Chromium 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 org.chromium.base.test; + +import android.app.Activity; +import android.content.Context; +import android.os.SystemClock; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; + +import org.chromium.base.BaseChromiumApplication; +import org.chromium.base.CommandLine; +import org.chromium.base.test.util.CommandLineFlags; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Base class for all Activity-based Instrumentation tests. + * + * @param <T> The Activity type. + */ +public class BaseActivityInstrumentationTestCase<T extends Activity> + extends ActivityInstrumentationTestCase2<T> { + + private static final String TAG = "BaseActivityInstrumentationTestCase"; + + private static final int SLEEP_INTERVAL = 50; // milliseconds + private static final int WAIT_DURATION = 5000; // milliseconds + + /** + * Creates a instance for running tests against an Activity of the given class. + * + * @param activityClass The type of activity that will be tested. + */ + public BaseActivityInstrumentationTestCase(Class<T> activityClass) { + super(activityClass); + } + + /** + * Sets up the CommandLine with the appropriate flags. + * + * This will add the difference of the sets of flags specified by {@link CommandLineFlags.Add} + * and {@link CommandLineFlags.Remove} to the {@link org.chromium.base.CommandLine}. Note that + * trying to remove a flag set externally, i.e. by the command-line flags file, will not work. + */ + @Override + protected void setUp() throws Exception { + super.setUp(); + + CommandLine.reset(); + Context targetContext = getTargetContext(); + assertNotNull("Unable to get a non-null target context.", targetContext); + + BaseChromiumApplication.initCommandLine(targetContext); + Set<String> flags = getFlags(getClass().getMethod(getName())); + for (String flag : flags) { + CommandLine.getInstance().appendSwitch(flag); + } + } + + /** + * Gets the target context. + * + * On older versions of Android, getTargetContext() may initially return null, so we have to + * wait for it to become available. + * + * @return The target {@link android.content.Context} if available; null otherwise. + */ + private Context getTargetContext() { + Context targetContext = getInstrumentation().getTargetContext(); + try { + long startTime = SystemClock.uptimeMillis(); + // TODO(jbudorick): Convert this to CriteriaHelper once that moves to base/. + while (targetContext == null + && SystemClock.uptimeMillis() - startTime < WAIT_DURATION) { + Thread.sleep(SLEEP_INTERVAL); + targetContext = getInstrumentation().getTargetContext(); + } + } catch (InterruptedException e) { + Log.e(TAG, "Interrupted while attempting to initialize the command line."); + } + return targetContext; + } + + private static Set<String> getFlags(AnnotatedElement element) { + AnnotatedElement parent = (element instanceof Method) + ? ((Method) element).getDeclaringClass() + : ((Class) element).getSuperclass(); + Set<String> flags = (parent == null) ? new HashSet<String>() : getFlags(parent); + + if (element.isAnnotationPresent(CommandLineFlags.Add.class)) { + flags.addAll( + Arrays.asList(element.getAnnotation(CommandLineFlags.Add.class).value())); + } + + if (element.isAnnotationPresent(CommandLineFlags.Remove.class)) { + List<String> flagsToRemove = + Arrays.asList(element.getAnnotation(CommandLineFlags.Remove.class).value()); + for (String flagToRemove : flagsToRemove) { + // If your test fails here, you have tried to remove a command-line flag via + // CommandLineFlags.Remove that was loaded into CommandLine via something other + // than CommandLineFlags.Add (probably the command-line flag file). + assertFalse("Unable to remove command-line flag \"" + flagToRemove + "\".", + CommandLine.getInstance().hasSwitch(flagToRemove)); + } + flags.removeAll(flagsToRemove); + } + + return flags; + } +} diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java b/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java new file mode 100644 index 0000000..2feb83d --- /dev/null +++ b/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java @@ -0,0 +1,48 @@ +// Copyright 2015 The Chromium 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 org.chromium.base.test.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Provides annotations related to command-line flag handling. + * + * Uses of these annotations on a derived class will take precedence over uses on its base classes, + * so a derived class can add a command-line flag that a base class has removed (or vice versa). + * Similarly, uses of these annotations on a test method will take precedence over uses on the + * containing class. + * + * Note that this class should never be instantiated. + */ +public final class CommandLineFlags { + + /** + * Adds command-line flags to the {@link org.chromium.base.CommandLine} for this test. + */ + @Inherited + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.METHOD, ElementType.TYPE}) + public @interface Add { + String[] value(); + } + + /** + * Removes command-line flags from the {@link org.chromium.base.CommandLine} from this test. + * + * Note that this can only remove flags added via {@link Add} above. + */ + @Inherited + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.METHOD, ElementType.TYPE}) + public @interface Remove { + String[] value(); + } + + private CommandLineFlags() {} +} |