Add the scrollFeed and flingFeed with speed method for IGoogleHelper.java am: 4d23e05671 am: ee95bd36bf

Original change: https://googleplex-android-review.googlesource.com/c/platform/platform_testing/+/12816060

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I5ceb78cf0b67eaa1365663b0b56a01e91070d010
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoLocationSettingsHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoLocationSettingsHelper.java
new file mode 100644
index 0000000..50228ba
--- /dev/null
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoLocationSettingsHelper.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.platform.helpers;
+
+public interface IAutoLocationSettingsHelper extends IAppHelper {
+    /** enum class for State. */
+    enum State {
+        ON,
+        OFF
+    }
+
+    /**
+     * Setup expectations: Location setting is open
+     *
+     * <p>Toggle on/off location switch
+     *
+     * @param state of toggle switch.
+     */
+    void toggleLocationSwitchOnOff(State state);
+
+    /**
+     * Setup expectations: Location setting is open
+     *
+     * <p>Check if location switch is toggled on.
+     */
+    boolean isLocationSwitchOn();
+
+    /**
+     * Setup expectations: None
+     *
+     * <p>Get device longitude.
+     */
+    double getLongitude();
+
+    /**
+     * Setup expectations: None
+     *
+     * <p>get device latitude.
+     */
+    double getLatitude();
+}
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterHelper.java
index e69e4ce..92180a6 100644
--- a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterHelper.java
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterHelper.java
@@ -18,65 +18,67 @@
 
 public interface IAutoMediaCenterHelper extends IAppHelper {
 
-  /**
-   * Setup expectations: Media test app is open.
-   *
-   * This method is used to set account type.
-   */
-  void setAccountType(String accountType);
+    /** enum for screen state */
+    enum ScreenState {
+        HOME,
+        NOW_PLAYING,
+    }
 
-  /**
-   * Setup expectations: Media test app is open.
-   *
-   * This method is used to set root node type.
-   */
-  void setRootNodeType(String rootNodeType);
+    /** enum for account type state */
+    enum AccountTypeState {
+        NONE,
+        FREE,
+        PAID,
+    }
 
-  /**
-   * Setup expectations: Media test app is open.
-   *
-   * This method is used to set root reply delay.
-   */
-  void setRootReplyDelay(String rootReplyDelay);
+    /**
+     * Setup expectations: Media test app is open.
+     *
+     * <p>This method is used to set account type.
+     */
+    void setAccountType(String accountType);
 
-  /**
-   * Setup expectations: media test app is open.
-   *
-   * This method is used to open Folder Menu with menuOptions.
-   * Example - openMenu->Folder->Mediafilename->trackName
-   *           openMenuWith(Folder,mediafilename,trackName);
-   *
-   * @param - menuOptions used to pass multiple level of menu options in one go.
-   */
-  void selectMediaTrack(String... menuOptions);
+    /**
+     * Setup expectations: Media test app is open.
+     *
+     * <p>This method is used to set root node type.
+     */
+    void setRootNodeType(String rootNodeType);
 
-  /**
-   * Setup expectations: media test app is open.
-   *
-   * This method is used to open settings.
-   */
-  void openSettings();
+    /**
+     * Setup expectations: Media test app is open.
+     *
+     * <p>This method is used to set root reply delay.
+     */
+    void setRootReplyDelay(String rootReplyDelay);
 
-  /**
-   * Setup expectations: media test app is open.
-   *
-   * This method is used to close settings.
-   */
-  void closeSettings();
+    /**
+     * Setup expectations: media test app is open.
+     *
+     * <p>This method is used to open settings.
+     */
+    void openSettings();
 
-  /**
-   * Setup expectations: media test app is open.
-   *
-   * @param - tabName used to select tab name.
-   */
-  void selectTab(String tabName);
+    /**
+     * Setup expectations: media test app is open.
+     *
+     * <p>This method is used to close settings.
+     */
+    void closeSettings();
 
-  /**
-   * Setup expectations: media test app is open.
-   *
-   * @param - title used search media track,artist.
-   */
-  void search(String title);
+    /**
+     * Setup expectations: media test app is open.
+     *
+     * @param - tabName used to select tab name.
+     */
+    void selectTab(String tabName);
+
+    /**
+     * Setup expectations: media test app is open.
+     *
+     * @param - title used search media track,artist.
+     */
+    void search(String title);
 
     /**
      * This method is used to check if media is currently playing Returns true if media is playing
@@ -97,4 +99,15 @@
      * clicks to go back to previous screen
      */
     void clickBackButton();
+
+    /**
+     * Setup expectations: media test app is open.
+     *
+     * <p>This method is used to open Folder Menu with menuOptions and scroll into view the track.
+     * Example - openMenu->Folder->Mediafilename->trackName
+     * openMenuWith(Folder,mediafilename,trackName);
+     *
+     * @param - menuOptions used to pass multiple level of menu options in one go.
+     */
+    void selectMediaTrack(String... menuOptions);
 }
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterMinimizeControlBarHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterMinimizeControlBarHelper.java
index f90c0ae..f8fca51 100644
--- a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterMinimizeControlBarHelper.java
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterMinimizeControlBarHelper.java
@@ -18,45 +18,45 @@
 
 public interface IAutoMediaCenterMinimizeControlBarHelper extends IAppHelper {
 
-  /**
-   * Setup expectations: media test app is open and Minimize control bar present.
-   *
-   * This method is used to play media.
-   */
-  void playMedia();
+    /**
+     * Setup expectations: media test app is open and Minimize control bar present.
+     *
+     * <p>This method is used to play media.
+     */
+    void playMedia();
 
-  /**
-   * Setup expectations: media test app is open and Minimize control bar present.
-   *
-   * This method is used to pause media.
-   */
-  void pauseMedia();
+    /**
+     * Setup expectations: media test app is open and Minimize control bar present.
+     *
+     * <p>This method is used to pause media.
+     */
+    void pauseMedia();
 
-  /**
-   * Setup expectations: media test app is open and Minimize control bar present.
-   *
-   * This method is used to select next track.
-   */
-  void clickNextTrack();
+    /**
+     * Setup expectations: media test app is open and Minimize control bar present.
+     *
+     * <p>This method is used to select next track.
+     */
+    void clickNextTrack();
 
-  /**
-   *  Setup expectations: media test app is open and Minimize control bar present.
-   *
-   * This method is used to select previous track.
-   */
-  void clickPreviousTrack();
+    /**
+     * Setup expectations: media test app is open and Minimize control bar present.
+     *
+     * <p>This method is used to select previous track.
+     */
+    void clickPreviousTrack();
 
-  /**
-   * Setup expectations: media test app is open and Minimize control bar present.
-   *
-   * @return to get current playing track name from home screen.
-   */
-  String getTrackName();
+    /**
+     * Setup expectations: media test app is open and Minimize control bar present.
+     *
+     * @return to get current playing track name from home screen.
+     */
+    String getTrackName();
 
-  /**
-   * Setup expectations: media test app is open and Minimize control bar present.
-   *
-   * This method is used to maximize the play back screen.
-   */
-  void maximizeNowPlaying();
+    /**
+     * Setup expectations: media test app is open and Minimize control bar present.
+     *
+     * <p>This method is used to maximize the play back screen.
+     */
+    void maximizeNowPlaying();
 }
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterNowPlayingHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterNowPlayingHelper.java
index a73e19b..9ebd215 100644
--- a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterNowPlayingHelper.java
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMediaCenterNowPlayingHelper.java
@@ -18,52 +18,52 @@
 
 public interface IAutoMediaCenterNowPlayingHelper extends IAppHelper {
 
-  /**
-   * Setup expectations: Now Playing is open.
-   *
-   * This method is used to play media.
-   */
-  void playMedia();
+    /**
+     * Setup expectations: Now Playing is open.
+     *
+     * <p>This method is used to play media.
+     */
+    void playMedia();
 
-  /**
-   * Setup expectations: Now Playing is open.
-   *
-   * This method is used to pause media.
-   */
-  void pauseMedia();
+    /**
+     * Setup expectations: Now Playing is open.
+     *
+     * <p>This method is used to pause media.
+     */
+    void pauseMedia();
 
-  /**
-   * Setup expectations: Now Playing is open.
-   *
-   * This method is used to select next track.
-   */
-  void clickNextTrack();
+    /**
+     * Setup expectations: Now Playing is open.
+     *
+     * <p>This method is used to select next track.
+     */
+    void clickNextTrack();
 
-  /**
-   *  Setup expectations: Now Playing is open.
-   *
-   * This method is used to select previous track.
-   */
-  void clickPreviousTrack();
+    /**
+     * Setup expectations: Now Playing is open.
+     *
+     * <p>This method is used to select previous track.
+     */
+    void clickPreviousTrack();
 
-  /**
-   * Setup expectations: Now Playing is open.
-   *
-   * @return to get current playing track name from screen.
-   */
-  String getTrackName();
+    /**
+     * Setup expectations: Now Playing is open.
+     *
+     * @return to get current playing track name from home screen.
+     */
+    String getTrackName();
 
-  /**
-   * Setup expectations: Now Playing is open.
-   *
-   * @return to get current playing track's artist name from screen.
-   */
-  String getArtistName();
+    /**
+     * Setup expectations: Now Playing is open.
+     *
+     * @return to get current playing track's artist name from screen.
+     */
+    String getArtistName();
 
-  /**
-   * Setup expectations: Now Playing is open.
-   *
-   * This method is used to minimize now playing.
-   */
-  void minimizeNowPlaying();
-}
\ No newline at end of file
+    /**
+     * Setup expectations: Now Playing is open.
+     *
+     * <p>This method is used to minimize now playing.
+     */
+    void minimizeNowPlaying();
+}
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSettingHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSettingHelper.java
index 7ad7084..7f6a00d 100644
--- a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSettingHelper.java
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSettingHelper.java
@@ -219,4 +219,13 @@
      * @param item to be verified.
      */
     boolean isValidPageTitle(String item);
+
+    /**
+     * Setup expectations: Setting is open.
+     *
+     * <p>check whether a setting menu in Settings is enabled or not.
+     *
+     * @param name of the setting menu.
+     */
+    boolean isSettingMenuEnabled(String menu);
 }
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSoundsSettingHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSoundsSettingHelper.java
new file mode 100644
index 0000000..5e948b2
--- /dev/null
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSoundsSettingHelper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.platform.helpers;
+
+public interface IAutoSoundsSettingHelper extends IAppHelper {
+
+    /** enum class for volume types. */
+    enum VolumeType {
+        MEDIA,
+        ALARM,
+        NAVIGATION,
+        INCALL,
+        NOTIFICATION,
+        RINGTONE
+    }
+
+    /** enum class for sound types. */
+    enum SoundType {
+        RINGTONE,
+        NOTIFICATION,
+        ALARM
+    }
+
+    /**
+     * Setup expectation: Sound setting is open.
+     *
+     * <p>get volume value.
+     *
+     * @param volumeType type selected.
+     */
+    int getVolume(VolumeType volumeType);
+
+    /**
+     * Setup expectation: Sound setting is open.
+     *
+     * <p>set volume
+     *
+     * @param volumeType type selected
+     * @param index index of sound value.
+     */
+    void setVolume(VolumeType volumeType, int index);
+
+    /**
+     * Setup expectation: Sound setting is open.
+     *
+     * <p>get sound.
+     *
+     * @param soundType type selected.
+     */
+    String getSound(SoundType soundType);
+
+    /**
+     * Setup expectation: Sound setting is open.
+     *
+     * <p>set sound
+     *
+     * @param soundType type selected.
+     * @param sound sound selected.
+     */
+    void setSound(SoundType soundType, String sound);
+}
diff --git a/libraries/health/rules/src/android/platform/test/rule/CompilationFilterRule.java b/libraries/health/rules/src/android/platform/test/rule/CompilationFilterRule.java
index 092aa8d..1316fe9 100644
--- a/libraries/health/rules/src/android/platform/test/rule/CompilationFilterRule.java
+++ b/libraries/health/rules/src/android/platform/test/rule/CompilationFilterRule.java
@@ -18,6 +18,7 @@
 
 import static java.util.stream.Collectors.joining;
 
+import android.os.SystemClock;
 import android.util.Log;
 import androidx.annotation.VisibleForTesting;
 
@@ -26,16 +27,23 @@
 import org.junit.runner.Description;
 import org.junit.runners.model.InitializationError;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /** This rule compiles the applications with the specified filter, or skips if unspecified. */
 public class CompilationFilterRule extends TestWatcher {
     //
     private static final String LOG_TAG = CompilationFilterRule.class.getSimpleName();
     // Compilation constants
     @VisibleForTesting static final String COMPILE_CMD_FORMAT = "cmd package compile -f -m %s %s";
+    @VisibleForTesting static final String DUMP_PROFILE_CMD = "killall -s SIGUSR1 %s";
     private static final ImmutableList<String> COMPILE_FILTER_LIST =
             ImmutableList.of("speed", "speed-profile", "quicken", "verify");
+    @VisibleForTesting static final String SPEED_PROFILE_FILTER = "speed-profile";
+    private static final String PROFILE_SAVE_TIMEOUT = "profile-save-timeout";
     @VisibleForTesting static final String COMPILE_FILTER_OPTION = "compilation-filter";
     @VisibleForTesting static final String COMPILE_SUCCESS = "Success";
+    private static Set<String> mCompiledTests = new HashSet<>();
 
     private final String[] mApplications;
 
@@ -48,9 +56,12 @@
     }
 
     @Override
-    protected void starting(Description description) {
+    protected void finished(Description description) {
         // Identify the filter option to use.
         String filter = getArguments().getString(COMPILE_FILTER_OPTION);
+        // Default speed profile save timeout set to 5 secs.
+        long profileSaveTimeout = Integer
+                .parseInt(getArguments().getString(PROFILE_SAVE_TIMEOUT, "5000"));
         if (filter == null) {
             // No option provided, default to a no-op.
             Log.d(LOG_TAG, "Skipping complation because filter option is unset.");
@@ -61,13 +72,38 @@
                     String.format(
                             "Unknown compiler filter: %s, not part of %s", filter, filterOptions));
         }
-        // Compile each application in sequence.
-        for (String app : mApplications) {
-            String response = executeShellCommand(String.format(COMPILE_CMD_FORMAT, filter, app));
-            if (!response.contains(COMPILE_SUCCESS)) {
-                Log.d(LOG_TAG, String.format("Received response: %s", response));
-                throw new RuntimeException(String.format("Failed to compile %s.", app));
+        // Profile varies based on the test even for the same app. Tracking the test id to make
+        // sure the test compiled once after the first iteration of the test.
+        String testId = description.getDisplayName();
+        if (!mCompiledTests.contains(testId)) {
+            for (String app : mApplications) {
+                // For speed profile compilation, ART team recommended to wait for 5 secs when app
+                // is in the foreground, dump the profile, wait for another 5 secs before
+                // speed-profile compilation.
+                if (filter.equalsIgnoreCase(SPEED_PROFILE_FILTER)) {
+                    SystemClock.sleep(profileSaveTimeout);
+                    // Send SIGUSR1 to force dumping a profile.
+                    String response = executeShellCommand(String.format(DUMP_PROFILE_CMD, app));
+                    if (!response.isEmpty()) {
+                        Log.d(LOG_TAG,
+                                String.format("Received dump profile cmd response: %s", response));
+                        throw new RuntimeException(
+                                String.format("Failed to dump profile %s.", app));
+                    }
+                    // killall is async, wait few seconds to let the app save the profile.
+                    SystemClock.sleep(profileSaveTimeout);
+                }
+                String response = executeShellCommand(
+                        String.format(COMPILE_CMD_FORMAT, filter, app));
+                if (!response.contains(COMPILE_SUCCESS)) {
+                    Log.d(LOG_TAG, String.format("Received compile cmd response: %s", response));
+                    throw new RuntimeException(String.format("Failed to compile %s.", app));
+                } else {
+                    mCompiledTests.add(testId);
+                }
             }
+        } else {
+            Log.d(LOG_TAG, String.format("Test %s already compiled", testId));
         }
     }
 }
diff --git a/libraries/health/rules/tests/src/android/platform/test/rule/CompilationFilterRuleTest.java b/libraries/health/rules/tests/src/android/platform/test/rule/CompilationFilterRuleTest.java
index 42a444d..974c032 100644
--- a/libraries/health/rules/tests/src/android/platform/test/rule/CompilationFilterRuleTest.java
+++ b/libraries/health/rules/tests/src/android/platform/test/rule/CompilationFilterRuleTest.java
@@ -49,8 +49,8 @@
     public void testAppToCompile_badFilterThrows() throws Throwable {
         Bundle badFilterBundle = new Bundle();
         badFilterBundle.putString(CompilationFilterRule.COMPILE_FILTER_OPTION, "bad-option");
-        TestableCompilationFilterRule rule =
-                new TestableCompilationFilterRule(badFilterBundle, "example.package");
+        TestableCompilationFilterRule rule = new TestableCompilationFilterRule(badFilterBundle,
+                "example.package");
         try {
             rule.apply(rule.getTestStatement(), TEST_DESC).evaluate();
             fail("An exception should have been thrown about bad filter, but wasn't.");
@@ -58,19 +58,19 @@
         }
     }
 
-    /** Tests that this rule will compile one app before the test, if supplied. */
+    /** Tests that this rule will compile one app after the test, if supplied. */
     @Test
     public void testAppToCompile_failCompilationThrows() throws Throwable {
-        Bundle badFilterBundle = new Bundle();
-        badFilterBundle.putString(CompilationFilterRule.COMPILE_FILTER_OPTION, "speed");
-        TestableCompilationFilterRule rule =
-                new TestableCompilationFilterRule(badFilterBundle, "example.package") {
-                    @Override
-                    protected String executeShellCommand(String cmd) {
-                        super.executeShellCommand(cmd);
-                        return "Error";
-                    }
-                };
+        Bundle filterBundle = new Bundle();
+        filterBundle.putString(CompilationFilterRule.COMPILE_FILTER_OPTION, "speed");
+        TestableCompilationFilterRule rule = new TestableCompilationFilterRule(filterBundle,
+                "example.package") {
+            @Override
+            protected String executeShellCommand(String cmd) {
+                super.executeShellCommand(cmd);
+                return "Error";
+            }
+        };
         try {
             rule.apply(rule.getTestStatement(), TEST_DESC).evaluate();
             fail("An exception should have been thrown about compilation failure, but wasn't.");
@@ -78,48 +78,81 @@
         }
     }
 
-    /** Tests that this rule will compile one app before the test, if supplied. */
+    /** Tests that this rule will compile one app after the test, if supplied. */
     @Test
     public void testOneAppToCompile() throws Throwable {
-        Bundle badFilterBundle = new Bundle();
-        badFilterBundle.putString(CompilationFilterRule.COMPILE_FILTER_OPTION, "speed");
-        TestableCompilationFilterRule rule =
-                new TestableCompilationFilterRule(badFilterBundle, "example.package") {
-                    @Override
-                    protected String executeShellCommand(String cmd) {
-                        super.executeShellCommand(cmd);
-                        return CompilationFilterRule.COMPILE_SUCCESS;
-                    }
-                };
-        rule.apply(rule.getTestStatement(), TEST_DESC).evaluate();
-        String compileCmd =
-                String.format(CompilationFilterRule.COMPILE_CMD_FORMAT, "speed", "example.package");
-        assertThat(rule.getOperations()).containsExactly(compileCmd, "test").inOrder();
+        Bundle filterBundle = new Bundle();
+        filterBundle.putString(CompilationFilterRule.COMPILE_FILTER_OPTION, "speed");
+        TestableCompilationFilterRule rule = new TestableCompilationFilterRule(filterBundle,
+                "example.package") {
+            @Override
+            protected String executeShellCommand(String cmd) {
+                super.executeShellCommand(cmd);
+                return CompilationFilterRule.COMPILE_SUCCESS;
+            }
+        };
+        rule.apply(rule.getTestStatement(), Description.createTestDescription("clzz", "mthd1"))
+                .evaluate();
+        String compileCmd = String.format(CompilationFilterRule.COMPILE_CMD_FORMAT, "speed",
+                "example.package");
+        assertThat(rule.getOperations()).containsExactly("test", compileCmd)
+                .inOrder();
     }
 
-    /** Tests that this rule will compile multiple apps before the test, if supplied. */
+    /** Tests that this rule will compile multiple apps after the test, if supplied. */
     @Test
     public void testMultipleAppsToCompile() throws Throwable {
-        Bundle badFilterBundle = new Bundle();
-        badFilterBundle.putString(CompilationFilterRule.COMPILE_FILTER_OPTION, "speed");
-        TestableCompilationFilterRule rule =
-                new TestableCompilationFilterRule(
-                        badFilterBundle, "example.package1", "example.package2") {
-                    @Override
-                    protected String executeShellCommand(String cmd) {
-                        super.executeShellCommand(cmd);
-                        return CompilationFilterRule.COMPILE_SUCCESS;
-                    }
-                };
-        rule.apply(rule.getTestStatement(), TEST_DESC).evaluate();
-        String compileCmd1 =
-                String.format(
-                        CompilationFilterRule.COMPILE_CMD_FORMAT, "speed", "example.package1");
-        String compileCmd2 =
-                String.format(
-                        CompilationFilterRule.COMPILE_CMD_FORMAT, "speed", "example.package2");
+        Bundle filterBundle = new Bundle();
+        filterBundle.putString(CompilationFilterRule.COMPILE_FILTER_OPTION, "speed");
+        TestableCompilationFilterRule rule = new TestableCompilationFilterRule(filterBundle,
+                "example.package1", "example.package2") {
+            @Override
+            protected String executeShellCommand(String cmd) {
+                super.executeShellCommand(cmd);
+                return CompilationFilterRule.COMPILE_SUCCESS;
+            }
+        };
+        rule.apply(rule.getTestStatement(), Description.createTestDescription("clzz", "mthd2"))
+                .evaluate();
+        String compileCmd1 = String.format(
+                CompilationFilterRule.COMPILE_CMD_FORMAT, "speed", "example.package1");
+        String compileCmd2 = String.format(
+                CompilationFilterRule.COMPILE_CMD_FORMAT, "speed", "example.package2");
         assertThat(rule.getOperations())
-                .containsExactly(compileCmd1, compileCmd2, "test")
+                .containsExactly("test", compileCmd1, compileCmd2)
+                .inOrder();
+    }
+
+    /** Tests that this rule will speed profile compile multiple apps after the test,
+     *  if supplied. */
+    @Test
+    public void testMultipleAppsToCompileInSpeedProfile() throws Throwable {
+        Bundle filterBundle = new Bundle();
+        filterBundle.putString(CompilationFilterRule.COMPILE_FILTER_OPTION,
+                CompilationFilterRule.SPEED_PROFILE_FILTER);
+        TestableCompilationFilterRule rule = new TestableCompilationFilterRule(filterBundle,
+                "example.package1", "example.package2") {
+            @Override
+            protected String executeShellCommand(String cmd) {
+                super.executeShellCommand(cmd);
+                if (cmd.contains("killall -s SIGUSR1")) {
+                    return "";
+                }
+                return CompilationFilterRule.COMPILE_SUCCESS;
+            }
+        };
+        rule.apply(rule.getTestStatement(), Description.createTestDescription("clzz", "mthd3"))
+                .evaluate();
+        String dumpCmd1 = String.format(CompilationFilterRule.DUMP_PROFILE_CMD,
+                "example.package1");
+        String compileCmd1 = String.format(CompilationFilterRule.COMPILE_CMD_FORMAT,
+                CompilationFilterRule.SPEED_PROFILE_FILTER, "example.package1");
+        String dumpCmd2 = String.format(CompilationFilterRule.DUMP_PROFILE_CMD,
+                "example.package2");
+        String compileCmd2 = String.format(CompilationFilterRule.COMPILE_CMD_FORMAT,
+                CompilationFilterRule.SPEED_PROFILE_FILTER, "example.package2");
+        assertThat(rule.getOperations())
+                .containsExactly("test", dumpCmd1, compileCmd1, dumpCmd2, compileCmd2)
                 .inOrder();
     }
 
diff --git a/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java b/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java
index 8a3db41..f812b99 100644
--- a/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java
+++ b/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java
@@ -42,7 +42,6 @@
         mKnownLauncherStrategies = new HashSet<>();
         registerLauncherStrategy(AospLauncherStrategy.class);
         registerLauncherStrategy(AutoLauncherStrategy.class);
-        registerLauncherStrategy(VolvoLauncherStrategy.class);
         registerLauncherStrategy(GoogleExperienceLauncherStrategy.class);
         registerLauncherStrategy(Launcher3Strategy.class);
         registerLauncherStrategy(NexusLauncherStrategy.class);
diff --git a/libraries/launcher-helper/src/android/support/test/launcherhelper/VolvoLauncherStrategy.java b/libraries/launcher-helper/src/android/support/test/launcherhelper/VolvoLauncherStrategy.java
deleted file mode 100644
index d0cac61..0000000
--- a/libraries/launcher-helper/src/android/support/test/launcherhelper/VolvoLauncherStrategy.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.support.test.launcherhelper;
-
-import android.app.Instrumentation;
-import android.os.SystemClock;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.system.helpers.CommandsHelper;
-
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/** Implementation of {@link ILauncherStrategy} to support Volvo launcher */
-public class VolvoLauncherStrategy extends AutoLauncherStrategy {
-    private static final String VOLVO_LAUNCHER_PACKAGE = "com.volvocars.launcher";
-    private static final String SYSTEM_UI_PACKAGE = "com.android.systemui";
-
-    private static final Map<String, BySelector> FACET_MAP =
-            Stream.of(
-                            new Object[][] {
-                                {
-                                    "App Grid",
-                                    By.res(SYSTEM_UI_PACKAGE, "nav_bar_apps").clickable(true)
-                                },
-                            })
-                    .collect(
-                            Collectors.toMap(
-                                    data -> (String) data[0], data -> (BySelector) data[1]));
-
-    private static final Map<String, BySelector> APP_OPEN_VERIFIERS =
-            Stream.of(
-                            new Object[][] {
-                                {"App Grid", By.res(VOLVO_LAUNCHER_PACKAGE, "apps_pane")},
-                            })
-                    .collect(
-                            Collectors.toMap(
-                                    data -> (String) data[0], data -> (BySelector) data[1]));
-
-    private static final long APP_LAUNCH_TIMEOUT_MS = 10000;
-    private static final long UI_WAIT_TIMEOUT_MS = 5000;
-    private static final long POLL_INTERVAL = 100;
-
-    protected UiDevice mDevice;
-    private Instrumentation mInstrumentation;
-    private CommandsHelper mCommandsHelper;
-
-    @Override
-    public String getSupportedLauncherPackage() {
-        return VOLVO_LAUNCHER_PACKAGE;
-    }
-
-    @Override
-    public void setUiDevice(UiDevice uiDevice) {
-        mDevice = uiDevice;
-    }
-
-    @Override
-    public void setInstrumentation(Instrumentation instrumentation) {
-        super.setInstrumentation(instrumentation);
-        mInstrumentation = instrumentation;
-        mCommandsHelper = CommandsHelper.getInstance(mInstrumentation);
-    }
-
-    @Override
-    public void openApp(String appName) {
-        if (checkApplicationExists(appName)) {
-            UiObject2 app = mDevice.findObject(By.clickable(true).hasDescendant(By.text(appName)));
-            app.clickAndWait(Until.newWindow(), APP_LAUNCH_TIMEOUT_MS);
-            mDevice.waitForIdle();
-        } else {
-            throw new RuntimeException(String.format("Application %s not found", appName));
-        }
-    }
-
-    @Override
-    public void openBluetoothAudioApp() {
-        String appName = "Bluetooth Media Player";
-        if (checkApplicationExists(appName)) {
-            UiObject2 app = mDevice.findObject(By.clickable(true).hasDescendant(By.text(appName)));
-            app.clickAndWait(Until.newWindow(), APP_LAUNCH_TIMEOUT_MS);
-            mDevice.waitForIdle();
-        } else {
-            throw new RuntimeException(String.format("Application %s not found", appName));
-        }
-    }
-
-    @Override
-    public void openGooglePlayStore() {
-        mDevice.pressHome();
-        mDevice.waitForIdle();
-        mCommandsHelper.executeShellCommand(
-                "am start -a android.intent.action.MAIN "
-                        + "-c android.intent.category.LAUNCHER "
-                        + "-n com.android.vending/"
-                        + "com.google.android.finsky.carmainactivity.MainActivity");
-    }
-
-    @Override
-    public boolean checkApplicationExists(String appName) {
-        openAppGridFacet();
-        UiObject2 app = findApplication(appName);
-        return app != null;
-    }
-
-    @Override
-    public void openAppGridFacet() {
-        openFacet("App Grid");
-    }
-
-    @Override
-    public void openMapsFacet() {
-        // Volvo does not have Facet for Maps, so open Maps from App Grid
-        openApp("Maps");
-    }
-
-    private void openFacet(String facetName) {
-        BySelector facetSelector = FACET_MAP.get(facetName);
-        UiObject2 facet = mDevice.findObject(facetSelector);
-        if (facet != null) {
-            facet.click();
-            waitUntilAppOpen(facetName, APP_LAUNCH_TIMEOUT_MS);
-        } else {
-            throw new RuntimeException(String.format("Failed to find %s facet.", facetName));
-        }
-    }
-
-    private void waitUntilAppOpen(String appName, long timeout) {
-        SystemClock.sleep(timeout);
-        long startTime = SystemClock.uptimeMillis();
-        boolean isOpen = false;
-        do {
-            isOpen = mDevice.hasObject(APP_OPEN_VERIFIERS.get(appName));
-            if (isOpen) {
-                break;
-            }
-            SystemClock.sleep(POLL_INTERVAL);
-        } while ((SystemClock.uptimeMillis() - startTime) < timeout);
-        if (!isOpen) {
-            throw new IllegalStateException(
-                    String.format(
-                            "Did not find any app of %s in foreground after %d ms.",
-                            appName, timeout));
-        }
-    }
-
-    private UiObject2 findApplication(String appName) {
-        BySelector appSelector = By.clickable(true).hasDescendant(By.text(appName));
-        return mDevice.findObject(appSelector);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void openNotifications() {
-        String cmd = "cmd statusbar expand-notifications";
-        mCommandsHelper.executeShellCommand(cmd);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void pressHome() {
-        String cmd = "input keyevent KEYCODE_HOME";
-        mCommandsHelper.executeShellCommand(cmd);
-    }
-}