diff --git a/libraries/base-app-helpers/src/android/platform/test/helpers/IRecentsHelper.java b/libraries/base-app-helpers/src/android/platform/test/helpers/IRecentsHelper.java
new file mode 100644
index 0000000..8a6f054
--- /dev/null
+++ b/libraries/base-app-helpers/src/android/platform/test/helpers/IRecentsHelper.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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.test.helpers;
+
+import android.support.test.uiautomator.Direction;
+
+public interface IRecentsHelper {
+    /**
+     * Setup expectations: "Recents" is open.
+     * <p>
+     * Flings the recent apps in the specified direction.
+     * </p>
+     * @param dir the direction for the apps to move
+     */
+    void flingRecents(Direction dir);
+
+    /**
+     * Setup expectations: "Recents" is open with content
+     * <p>
+     * Clears up open recent items. Nothing happens if there is no content.
+     * </p>
+     */
+    void clearAll();
+
+    /**
+     * Setup expectations: "Recents" is open.
+     *
+     * @return True if there is Recents content.
+     */
+    boolean hasContent();
+}
diff --git a/libraries/first-party-app-helpers/tv/Android.mk b/libraries/first-party-app-helpers/tv/Android.mk
index 9e0b7dd..8d64152 100644
--- a/libraries/first-party-app-helpers/tv/Android.mk
+++ b/libraries/first-party-app-helpers/tv/Android.mk
@@ -17,7 +17,10 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := leanback-app-helpers
-LOCAL_STATIC_JAVA_LIBRARIES := launcher-helper-lib base-app-helpers
+LOCAL_STATIC_JAVA_LIBRARIES := launcher-helper-lib base-app-helpers \
+                               tv-sysui-app-helper tv-youtube-app-helper tv-search-app-helper \
+                               tv-play-movies-app-helper \
+                               leanback-demo-app-helper
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
diff --git a/libraries/first-party-app-helpers/tv/leanback-demo-app-helper/Android.mk b/libraries/first-party-app-helpers/tv/leanback-demo-app-helper/Android.mk
new file mode 100644
index 0000000..dfa66bd
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/leanback-demo-app-helper/Android.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := leanback-demo-app-helper
+LOCAL_JAVA_LIBRARIES := ub-uiautomator base-app-helpers tv-sysui-app-helper
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
diff --git a/libraries/first-party-app-helpers/tv/leanback-demo-app-helper/src/android/platform/test/helpers/tv/LeanbackDemoHelperImpl.java b/libraries/first-party-app-helpers/tv/leanback-demo-app-helper/src/android/platform/test/helpers/tv/LeanbackDemoHelperImpl.java
new file mode 100644
index 0000000..ee73a56
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/leanback-demo-app-helper/src/android/platform/test/helpers/tv/LeanbackDemoHelperImpl.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 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.test.helpers.tv;
+
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.platform.test.helpers.AbstractLeanbackAppHelper;
+import android.platform.test.helpers.exceptions.UiTimeoutException;
+import android.platform.test.helpers.exceptions.UnknownUiException;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+
+public class LeanbackDemoHelperImpl extends AbstractLeanbackAppHelper {
+
+    private static final String TAG = LeanbackDemoHelperImpl.class.getSimpleName();
+    private static final String UI_PACKAGE = "com.example.android.tvleanback";
+    private static final String ACTIVITY_MAIN = "com.example.android.tvleanback.ui.MainActivity";
+    private static final String RES_MAIN_ACTIVITY_ID = "main_frame";
+    private static final long SHORT_SLEEP_MS = 5000;    // 5 seconds
+    private static final long LONG_SLEEP_MS = 30000;    // 30 seconds
+
+    private static final String TEXT_TOOLTIP = "Hold HOME to control PIP";
+
+
+    public LeanbackDemoHelperImpl(Instrumentation instrumentation) {
+        super(instrumentation);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getPackage() {
+        return UI_PACKAGE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getLauncherName() {
+        return "Videos by Google";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected BySelector getMainActivitySelector() {
+        return By.res(UI_PACKAGE, RES_MAIN_ACTIVITY_ID);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected BySelector getBrowseRowsSelector() {
+        return By.focused(true).hasChild(By.res(UI_PACKAGE, "main_image"));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void open() {
+        launchActivity();
+        // Wait until the main activity is open.
+        mDevice.wait(Until.hasObject(getMainActivitySelector()), SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Setup expectation: None
+     *
+     * Launches the demo main activity with an Intent.
+     */
+    private void launchActivity() {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        intent.setComponent(new ComponentName(UI_PACKAGE, ACTIVITY_MAIN));
+        // Launch the activity
+        mInstrumentation.getContext().startActivity(intent);
+    }
+
+    /**
+     * Setup expectation: On the main activity.
+     * <p>
+     * Selects the desired video in the row content and wait for it to open the details view.
+     * </p>
+     * @param sectionName the name of section that includes the desired video
+     * @param videoName the name of video to select
+     */
+    public void selectVideoInRowContent(String sectionName, String videoName) {
+        returnToMainActivity();
+        openHeader(sectionName);
+        UiObject2 container = getRowContent(sectionName);
+        BySelector target = By.focused(true).hasDescendant(
+                By.res(UI_PACKAGE, "title_text").text(videoName), 3);
+        UiObject2 video = select(container, target, Direction.RIGHT);
+        if (video == null) {
+            throw new UnknownUiException(
+                    String.format("The video %s not found in the %s section", videoName,
+                            sectionName));
+        }
+        mDPadHelper.pressDPadCenter();
+        mDevice.waitForIdle();
+    }
+
+    /**
+     * Setup expectation: On the details view.
+     * <p>
+     * Selects the button of "WATCH TRAILER FREE".
+     * </p>
+     */
+    public void selectWatchTrailer() {
+        BySelector target = By.res(UI_PACKAGE, "lb_action_button").text("WATCH TRAILER\nFREE");
+        UiObject2 trailer = mDevice.wait(Until.findObject(target), SHORT_SLEEP_MS);
+        if (trailer == null) {
+            throw new UnknownUiException("The watch trailer button not found");
+        }
+        mDPadHelper.pressDPadCenter();
+        mDevice.waitForIdle();
+    }
+
+    /**
+     * Setup expectation: On the media control card.
+     *
+     * @return a boolean of whether the media control card has a PIP button enabled.
+     */
+    public boolean hasPipButton() {
+        // Pressing the key up brings up the media control card
+        mDPadHelper.pressDPad(Direction.UP);
+        if (!mDevice.wait(Until.hasObject(By.res(UI_PACKAGE, "controls_card")), SHORT_SLEEP_MS)) {
+            throw new UiTimeoutException("No media control card is found");
+        }
+        return mDevice.wait(Until.hasObject(
+                By.res(UI_PACKAGE, "button").desc("Enter Picture In Picture Mode")),
+                SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Setup expectation: PIP window is being open.
+     *
+     * @return a boolean of whether the tooltip text is shown.
+     */
+    public boolean hasTooltipShown() {
+        return mDevice.wait(Until.hasObject(By.text(TEXT_TOOLTIP)), SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Setup expectation: While playing a video in fullscreen.
+     * <p>
+     * Clicks on the PIP button and wait for it to be gone.
+     * </p>
+     */
+    public void openMediaControlsAndClickPipButton() {
+        // Pressing the key up brings up the media control card
+        mDPadHelper.pressDPad(Direction.UP);
+        if (!mDevice.wait(Until.hasObject(By.res(UI_PACKAGE, "controls_card")), SHORT_SLEEP_MS)) {
+            throw new UiTimeoutException("No media control card is found");
+        }
+        BySelector target = By.res(UI_PACKAGE, "button").desc("Enter Picture In Picture Mode");
+        UiObject2 pipButton = mDevice.wait(Until.findObject(target), SHORT_SLEEP_MS);
+        if (pipButton == null) {
+            throw new UiTimeoutException("PIP button not found");
+        }
+        pipButton.click();
+        mDevice.waitForIdle();
+        mDPadHelper.pressDPadCenter();
+        mDevice.waitForIdle();
+    }
+
+    /**
+     * Attempts to return to main activity with getMainActivitySelector()
+     * by pressing the back button repeatedly and sleeping briefly to allow for UI slowness.
+     */
+    public void returnToMainActivity() {
+        int maxBackAttempts = 10;
+        BySelector selector = getMainActivitySelector();
+        if (selector == null) {
+            throw new IllegalStateException("getMainActivitySelector() should be overridden.");
+        }
+        while (!mDevice.wait(Until.hasObject(selector), SHORT_SLEEP_MS)
+                && maxBackAttempts-- > 0) {
+            mDevice.pressBack();
+        }
+    }
+
+    private UiObject2 getRowContent(String rowName) {
+        return mDevice.wait(Until.findObject(By.res(UI_PACKAGE, "row_content").desc(rowName)),
+                LONG_SLEEP_MS);
+    }
+}
+
diff --git a/libraries/first-party-app-helpers/tv/play-movies-app-helper/Android.mk b/libraries/first-party-app-helpers/tv/play-movies-app-helper/Android.mk
new file mode 100644
index 0000000..1d270f8
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/play-movies-app-helper/Android.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := tv-play-movies-app-helper
+LOCAL_JAVA_LIBRARIES := ub-uiautomator base-app-helpers
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
diff --git a/libraries/first-party-app-helpers/tv/play-movies-app-helper/src/android/platform/test/helpers/tv/PlayMoviesHelperImpl.java b/libraries/first-party-app-helpers/tv/play-movies-app-helper/src/android/platform/test/helpers/tv/PlayMoviesHelperImpl.java
new file mode 100644
index 0000000..b07b4f6
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/play-movies-app-helper/src/android/platform/test/helpers/tv/PlayMoviesHelperImpl.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2016 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.test.helpers.tv;
+
+import android.app.Instrumentation;
+import android.os.SystemClock;
+import android.platform.test.helpers.AbstractLeanbackAppHelper;
+import android.platform.test.helpers.CommandHelper;
+import android.platform.test.helpers.exceptions.UiTimeoutException;
+import android.platform.test.helpers.exceptions.UnknownUiException;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+public class PlayMoviesHelperImpl extends AbstractLeanbackAppHelper {
+
+    private static final String LOG_TAG = PlayMoviesHelperImpl.class.getSimpleName();
+    private static final String UI_PACKAGE = "com.google.android.videos";
+    private static final String RES_MAIN_ACTIVITY_ID = "browse_container_dock";
+    private static final String RES_SEARCH_ORB_ID = "title_orb";
+    private static final String RES_SEARCH_BOX_ID = "lb_search_text_editor";
+
+    private static final String TEXT_MOVIES = "Movies";
+    private static final String TEXT_MY_LIBRARY = "My library";
+    private static final String TEXT_PLAY_TRAILER = "PLAY TRAILER";
+
+    private static final long SHORT_SLEEP_MS = 5000;    // 5 seconds
+    private static final long LONG_SLEEP_MS = 30000;    // 30 seconds
+
+    private CommandHelper mCmdHelper;
+
+
+    public PlayMoviesHelperImpl(Instrumentation instrumentation) {
+        super(instrumentation);
+        mCmdHelper = new CommandHelper(instrumentation);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getPackage() {
+        return UI_PACKAGE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getLauncherName() {
+        return "Play Movies & TV";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected BySelector getMainActivitySelector() {
+        return By.res(UI_PACKAGE, RES_MAIN_ACTIVITY_ID);
+    }
+
+    /**
+     * Selects search orb. The app should be opened beforehand by calling open().
+     */
+    public void selectSearchOrb() {
+        returnToMainActivity();
+
+        // Wait until the search orb appears at runtime.
+        UiObject2 searchOrb = mDevice.wait(
+                Until.findObject(By.res(UI_PACKAGE, RES_SEARCH_ORB_ID).clickable(true)),
+                SHORT_SLEEP_MS);
+        if (searchOrb == null) {
+            throw new UiTimeoutException("Failed to select search orb");
+        }
+        searchOrb.click();
+    }
+
+    /**
+     * Searches for the given query and keep the search result open.
+     * Play Movies app should be opened beforehand by calling open().
+     *
+     * @param query a search query string typed in Play Movies' search box.
+     */
+    public void search(String query) {
+        selectSearchOrb();
+        mDevice.waitForIdle();
+
+        Log.v(LOG_TAG, "Searching for the movie: " + query);
+        UiObject2 editText = mDevice.wait(Until.findObject(
+                By.res(UI_PACKAGE, RES_SEARCH_BOX_ID)), SHORT_SLEEP_MS);
+        if (editText == null) {
+            throw new UnknownUiException("Search text editor not found");
+        }
+
+        int retries = 4;
+        while(!editText.isFocused() && retries > 0) {
+            mDevice.pressDPadRight();
+            mDevice.waitForIdle();
+            retries--;
+        }
+
+        // Set query and search
+        editText.setText(query);
+        SystemClock.sleep(SHORT_SLEEP_MS);
+
+        mDevice.pressEnter();
+        SystemClock.sleep(SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Finds a movie with the trailer from the search result and start playing.
+     * search() should be called right before calling this method.
+     */
+    public UiObject2 searchForMovieWithTrailer() {
+        mDevice.wait(Until.findObject(By.text(TEXT_MOVIES)), SHORT_SLEEP_MS);
+        mDevice.pressDPadCenter();
+        mDevice.waitForIdle();
+
+        // Skip until a trailer is found from the result
+        UiObject2 trailerButton = null;
+        final int MAX_ATTEMPTS_SEARCH_TRAILERS = 5;
+        for (long i = 0; i < MAX_ATTEMPTS_SEARCH_TRAILERS; i++) {
+            trailerButton = getTrailerButton();
+            if (trailerButton == null) {
+                // The trailer was not found for the movie,
+                // back and open the detail of the next movie
+                mDevice.pressBack();
+                mDevice.wait(Until.findObject(By.text(TEXT_MOVIES)), SHORT_SLEEP_MS);
+
+                mDevice.pressDPadRight();
+                SystemClock.sleep(SHORT_SLEEP_MS);
+
+                mDevice.pressDPadCenter();
+                mDevice.waitForIdle();
+            } else {
+                // The trailer was found for the movie
+                break;
+            }
+
+        }
+
+        SystemClock.sleep(SHORT_SLEEP_MS);
+        return trailerButton;
+    }
+
+    public UiObject2 getTrailerButton() {
+        return mDevice.wait(Until.findObject(By.text(TEXT_PLAY_TRAILER)), SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Setup expectations: Trailer is selected, and shown in details fragment.
+     *
+     * Play a trailer
+     */
+    public void playTrailerInDetails(long durationMs) {
+        UiObject2 trailerButton = getTrailerButton();
+        if (trailerButton == null) {
+            throw new UnknownUiException("Trailer action not found");
+        }
+        trailerButton.click();
+
+        // Using "Play trailer" to wait for the playback to start
+        mDevice.wait(Until.gone(By.text(TEXT_PLAY_TRAILER)),
+                SHORT_SLEEP_MS);
+
+        // Using "Play trailer" button to wait until the trailer finishes
+        trailerButton = mDevice.wait(
+                Until.findObject(By.text(TEXT_PLAY_TRAILER)), durationMs);
+        if (trailerButton == null) {
+            throw new RuntimeException("Trailer too long or something went wrong");
+        }
+    }
+
+    /**
+     * Open My Library section
+     */
+    public void openMyLibrary() {
+        returnToMainActivity();
+        openHeader(TEXT_MY_LIBRARY);
+    }
+
+    /**
+     * Setup expectations: None.
+     * Open My Movies in My library section, wait for the list of movies to come.
+     */
+    public void openMyMoviesList() {
+        openMyLibrary();
+        if (getCardByNameInRowContent(TEXT_MOVIES) == null) {
+            throw new UnknownUiException("Movies in My library not found");
+        }
+        mDevice.performActionAndWait(new Runnable() {
+            @Override
+            public void run() {
+                mDevice.pressDPadCenter();
+            }
+        }, Until.newWindow(), SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Get a card with the given name in row_content
+     *
+     * @param title of the card
+     * @return UIObject2 for the focusable button
+     */
+    private UiObject2 getCardByNameInRowContent(String title) {
+        UiObject2 container = mDevice.findObject(
+                By.res(getPackage(), "row_content").hasDescendant(By.focused(true)));
+        return select(container, By.res(getPackage(), "title_text").text(title),
+                Direction.RIGHT);
+    }
+
+    /**
+     * Setup expectations: The movie(s) is listed in the Vertical grid fragment
+     */
+    public void selectTheFocusedMovieInVerticalGrid() {
+        assertWidgetEquals(Widget.VERTICAL_GRID_FRAGMENT);
+        mDevice.performActionAndWait(new Runnable() {
+            @Override
+            public void run() {
+                mDevice.pressDPadCenter();
+            }
+        }, Until.newWindow(), SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Setup expectations: The movie to play is listed in the Details fragment
+     *
+     * Play the selected movies from beginning
+     */
+    public void playFromBeginning() {
+        assertWidgetEquals(Widget.DETAILS_FRAGMENT);
+
+        // Play from beginning
+        UiObject2 actionButton = mDevice.wait(Until.findObject(By.clazz(".Button")),
+                LONG_SLEEP_MS);
+        if (actionButton == null) {
+            throw new UnknownUiException("action button not found");
+        }
+        String selectedText = actionButton.getText();
+        Log.v(LOG_TAG, String.format("Selected text is: %s", selectedText));
+        while (!(selectedText.toLowerCase().equals("play from beginning") ||
+                selectedText.toLowerCase().equals("play movie"))) {
+            String prevText = selectedText;
+
+            // Select the next item
+            mDevice.pressDPadRight();
+
+            // Make sure the text has changed
+            selectedText = mDevice.findObject(By.clazz(".Button").focused(true)).getText();
+            if (selectedText.equals(prevText)) {
+                throw new UnknownUiException("'Play from beginning' or 'Play movie' not found");
+            }
+        }
+        mDevice.pressDPadCenter();
+
+        // Dismiss confirmation dialog if it's a rental movie
+        UiObject2 yesButton = mDevice.wait(
+                Until.findObject(By.res(UI_PACKAGE, "guidedactions_list")), SHORT_SLEEP_MS);
+        if (yesButton != null) {
+            mDevice.pressDPadCenter();
+        }
+    }
+
+    /**
+     * Get the current playback state for a given package that owns the media session.
+     * @param packageName the package name of media session owner
+     * @return
+     * 0 = PlaybackState.STATE_NONE
+     * 1 = PlaybackState.STATE_STOPPED
+     * 2 = PlaybackState.STATE_PAUSED
+     * 3 = PlaybackState.STATE_PLAYING
+     */
+    public int getPlaybackState(String packageName) {
+        String output = mCmdHelper.executeDumpsysMediaSession();
+        // Parse the output of dumpsys media_session.
+        // Example :
+        // LeanbackSampleApp com.example.android.tvleanback/LeanbackSampleApp
+        //   package=com.example.android.tvleanback
+        //   ...
+        //   state=PlaybackState {state=3, position=0, buffered position=0, speed=1.0, updated=...}
+        int playbackState = 0;
+        int index = output.indexOf(String.format("package=%s", packageName));
+        if (index == -1) {
+            Log.w(LOG_TAG, String.format("No media session found for the package: %s", packageName));
+            return playbackState;
+        }
+        final Pattern PLAYBACKSTATE_REGEX = Pattern.compile(
+                "\\s*state=PlaybackState \\{state=(\\d+),.*");
+        Matcher matcher = PLAYBACKSTATE_REGEX.matcher(output.substring(index));
+        if (matcher.find()) {
+            playbackState = Integer.parseInt(matcher.group(1));
+            Log.i(LOG_TAG, String.format("PlaybackState=%s package=%s", playbackState, packageName));
+        }
+        return playbackState;
+    }
+}
+
diff --git a/libraries/first-party-app-helpers/tv/search-app-helper/Android.mk b/libraries/first-party-app-helpers/tv/search-app-helper/Android.mk
new file mode 100644
index 0000000..3a38984
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/search-app-helper/Android.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := tv-search-app-helper
+LOCAL_JAVA_LIBRARIES := ub-uiautomator base-app-helpers
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
diff --git a/libraries/first-party-app-helpers/tv/search-app-helper/src/android/platform/test/helpers/tv/SearchHelperImpl.java b/libraries/first-party-app-helpers/tv/search-app-helper/src/android/platform/test/helpers/tv/SearchHelperImpl.java
new file mode 100644
index 0000000..a723e51
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/search-app-helper/src/android/platform/test/helpers/tv/SearchHelperImpl.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 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.test.helpers.tv;
+
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.platform.test.helpers.AbstractLeanbackAppHelper;
+import android.platform.test.helpers.exceptions.UiTimeoutException;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+
+public class SearchHelperImpl extends AbstractLeanbackAppHelper {
+
+    private static final String TAG = SearchHelperImpl.class.getSimpleName();
+    private static final String UI_PACKAGE = "com.google.android.katniss";
+    private static final String SEARCH_ACTIVITY_NAME =
+            "com.google.android.katniss.search.SearchActivity";
+    private static final long SHORT_SLEEP_MS = 3000;    // 3 seconds
+
+    private static Instrumentation  mInstrumentation;
+
+    public static final int VOICE_SEARCH = 1;
+    public static final int KEYBOARD_SEARCH = 2;
+
+
+    public SearchHelperImpl(Instrumentation instrumentation) {
+        super(instrumentation);
+        mInstrumentation = instrumentation;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getPackage() {
+        return UI_PACKAGE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getLauncherName() {
+        return null;
+    }
+
+    /**
+     * Setup expectations: None
+     *
+     * Starts the voice search activity for querying the content.
+     * @param searchType Type of search request (1=voice, 2=keyboard)
+     * @param searchQuery Query string
+     */
+    public void launchActivityAndQuery(int searchType, String searchQuery) {
+        Intent intent = new Intent("android.intent.action.ASSIST");
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addCategory("android.intent.category.DEFAULT");
+        intent.setComponent(new ComponentName(UI_PACKAGE, SEARCH_ACTIVITY_NAME));
+        intent.putExtra("search_type", searchType);
+        intent.putExtra("query", searchQuery);
+        mInstrumentation.getContext().startActivity(intent);
+        Log.d(TAG, String.format("launchActivityAndQuery searchType=%d query=%s", searchType,
+                searchQuery));
+
+        // Ensure that the package is open
+        if (isOpen(SHORT_SLEEP_MS) == false) {
+            throw new UiTimeoutException("The Search activity is not launched.");
+        }
+        if (isInKeyboardMode()) {
+            Log.i(TAG, "Search activity Is in keyboard mode. Pressing the ENTER key.");
+            mDPadHelper.pressEnter();
+            mDevice.waitForIdle();
+        }
+    }
+
+    public BySelector getSearchTextEditorSelector() {
+        return By.res(UI_PACKAGE, "search_text_editor");
+    }
+
+    public BySelector getResultContainerSelector() {
+        return By.res(UI_PACKAGE, "container_list");
+    }
+
+    public boolean isInKeyboardMode() {
+        return mDevice.hasObject(getSearchTextEditorSelector());
+    }
+
+    public boolean isOpen(long waitMs) {
+        return mDevice.wait(Until.hasObject(By.pkg(UI_PACKAGE).depth(0)), waitMs);
+    }
+}
+
diff --git a/libraries/first-party-app-helpers/tv/sysui-app-helper/Android.mk b/libraries/first-party-app-helpers/tv/sysui-app-helper/Android.mk
new file mode 100644
index 0000000..0926908
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/sysui-app-helper/Android.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := tv-sysui-app-helper
+LOCAL_JAVA_LIBRARIES := ub-uiautomator base-app-helpers
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
diff --git a/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/NoTouchAuthHelperImpl.java b/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/NoTouchAuthHelperImpl.java
new file mode 100644
index 0000000..1bb6d6b
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/NoTouchAuthHelperImpl.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2016 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.test.helpers.tv;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.platform.test.helpers.AbstractLeanbackAppHelper;
+import android.platform.test.helpers.DPadHelper;
+import android.platform.test.helpers.exceptions.UnknownUiException;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+
+/**
+ * App helper implementation class for the NoTouchAuthDelegate UI
+ * to add an account to non-touch device like TV.
+ */
+public class NoTouchAuthHelperImpl extends AbstractLeanbackAppHelper {
+    private static final String LOG_TAG = NoTouchAuthHelperImpl.class.getSimpleName();
+    private static final String UI_PACKAGE = "com.google.android.gsf.notouch";
+
+    private static final String TITLE_SIGN_IN_ONBOARDING = "Sign in to your account";
+    private static final String TITLE_SIGN_IN_ACCOUNT = "Enter your account email address";
+    private static final String TITLE_SIGN_IN_PASSWORD = "Enter your account password";
+    private static final String TITLE_SIGN_IN_ACCOUNT_ALREADY_EXISTS =
+            "This account already exists on your device";
+    private static final String TEXT_SIGN_IN_SECOND_SCREEN = "Use your phone or laptop";
+    private static final String TEXT_SIGN_IN_PASSWORD = "Use your password";
+
+    private static final long SHORT_SLEEP_MS = 3000;
+
+
+    private Context mContext;
+
+
+    public NoTouchAuthHelperImpl(Instrumentation instrumentation) {
+        super(instrumentation);
+        mDPadHelper = DPadHelper.getInstance(instrumentation);
+        mContext = instrumentation.getContext();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getPackage() {
+        return UI_PACKAGE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getLauncherName() {
+        throw new UnsupportedOperationException("This method is not supported for NoTouchAuth");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void open() {
+        throw new UnsupportedOperationException("This method is not supported for NoTouchAuth");
+    }
+
+    /**
+     * Setup expectations: The sign-in page is open.
+     * <p>
+     * Attempts to login with an account.
+     * </p>
+     * @return true if the attempt to login is successful. However this doesn't guarantee that
+     * the account is registered in AccountManager.
+     */
+    public boolean loginAccount(String accountName, String password) {
+        selectUseYourPassword();
+
+        // Enter the account name
+        if (!isSignInAccountPage()) {
+            throw new UnknownUiException("Failed to find the page to enter account");
+        }
+        setTextForSignIn(accountName);
+
+        // Check if the account already exists
+        if (isSignInAccountAlreadyExists()) {
+            Log.w(LOG_TAG, "Failed to log in with the account already registered.");
+            return false;
+        }
+
+        // Enter the password
+        if (!isSignInPasswordPage()) {
+            throw new UnknownUiException("Failed to find the page to enter password");
+        }
+        setTextForSignIn(password);
+        return true;
+    }
+
+    /**
+     * Setup expectations: The sign-in page is open.
+     * <p>
+     * Selects "Use Your Password".
+     * </p>
+     * @return
+     */
+    private void selectUseYourPassword() {
+        selectSignInOptions(TEXT_SIGN_IN_PASSWORD);
+        // Wait for it to open the page to enter account name
+        mDevice.waitForIdle();
+        if (!isSignInAccountPage()) {
+            throw new UnknownUiException("Failed to find the page to enter account name");
+        }
+    }
+
+    /**
+     * Setup expectations: The sign-in page is open. Selects "Use your phone or laptop" for
+     * Second Screen Setup.
+     * @return
+     */
+    private void selectUseYourPhoneOrLaptop() {
+        selectSignInOptions(TEXT_SIGN_IN_SECOND_SCREEN);
+    }
+
+    private boolean isSignInOnboardingPage() {
+        return TITLE_SIGN_IN_ONBOARDING.equals(getTitleText());
+    }
+
+    private boolean isSignInAccountPage() {
+        return TITLE_SIGN_IN_ACCOUNT.equals(getTitleText());
+    }
+
+    private boolean isSignInPasswordPage() {
+        return TITLE_SIGN_IN_PASSWORD.equals(getTitleText());
+    }
+
+    private boolean isSignInAccountAlreadyExists() {
+        return TITLE_SIGN_IN_ACCOUNT_ALREADY_EXISTS.equals(getTitleText());
+    }
+
+    private void selectSignInOptions(String optionString) {
+        if (!isSignInOnboardingPage()) {
+            throw new IllegalStateException("Should be on the sign in onboarding page");
+        }
+        UiObject2 action = mDevice.wait(Until.findObject(By.res(UI_PACKAGE, "action")),
+                SHORT_SLEEP_MS);
+        if (action == null) {
+            throw new UnknownUiException("The container 'action' for sign-in not found");
+        }
+        UiObject2 button = select(action,
+                By.res(UI_PACKAGE, "list_item_text").text(optionString),
+                Direction.DOWN);
+        if (button == null) {
+            throw new UnknownUiException("The button not found " + optionString);
+        }
+        mDPadHelper.pressDPadCenterAndWait(Until.newWindow(), SHORT_SLEEP_MS);
+    }
+
+    private String getTitleText() {
+        return mDevice.findObject(By.res(UI_PACKAGE, "title_text")).getText();
+    }
+
+    private void setTextForSignIn(String text) {
+        UiObject2 editText = mDevice.wait(Until.findObject(By.res(UI_PACKAGE, "text_input")),
+                SHORT_SLEEP_MS);
+        editText.setText(text);
+        mDPadHelper.pressEnterAndWait(Until.newWindow(), SHORT_SLEEP_MS);
+    }
+}
+
diff --git a/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/SysUiPipHelperImpl.java b/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/SysUiPipHelperImpl.java
new file mode 100644
index 0000000..60cab1a
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/SysUiPipHelperImpl.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2016 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.test.helpers.tv;
+
+import static android.view.KeyEvent.KEYCODE_WINDOW;
+
+import android.app.Instrumentation;
+import android.graphics.Rect;
+import android.platform.test.helpers.DPadHelper;
+import android.platform.test.helpers.CommandHelper;
+import android.platform.test.helpers.exceptions.UnknownUiException;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * App helper implementation class for TV's picture-in-picture in System UI
+ */
+public class SysUiPipHelperImpl {
+    private static final String LOG_TAG = SysUiPipHelperImpl.class.getSimpleName();
+    private static final String UI_PACKAGE = "com.android.systemui";
+    private static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
+    private static final int PINNED_STACK_ID = 4;   // ID of stack for a PIP window
+
+    private static final int INVALID_TASK_ID = -1;
+    private static final String ACTIVITY_PIPOVERLAY =
+            "com.android.systemui.tv.pip.PipOverlayActivity";
+    // Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows
+    private static final Rect PIP_MENU_BOUNDS = new Rect(596, 280, 1324, 690);
+    private static final Rect PIP_RECENTS_BOUNDS = new Rect(800, 54, 1120, 234);
+    private static final Rect PIP_RECENTS_FOCUSED_BOUNDS = new Rect(775, 54, 1145, 262);
+    private static final Rect PIP_SETTINGS_BOUNDS = new Rect(662, 54, 1142, 324);
+
+    private static final long SHORT_SLEEP_MS = 3000;    // 3 seconds
+
+    private DPadHelper mDPadHelper;
+    private CommandHelper mCmdHelper;
+    private UiDevice mDevice;
+
+
+    public SysUiPipHelperImpl(Instrumentation instrumentation) {
+        mDPadHelper = DPadHelper.getInstance(instrumentation);
+        mCmdHelper = new CommandHelper(instrumentation);
+        mDevice = UiDevice.getInstance(instrumentation);
+    }
+
+    /**
+     * @return the package name for this helper's application.
+     */
+    public String getPackage() {
+        return UI_PACKAGE;
+    }
+
+    /**
+     * Setup expectations: None
+     * <p>
+     * Checks if a PIP window is shown on screen.
+     * </p>
+     * @param activityName the activity of the application that implements PIP playback
+     */
+    public boolean isPipOnScreen(String activityName) {
+        String output = mCmdHelper.executeAmStackInfo(PINNED_STACK_ID);
+        Log.i(LOG_TAG, "isPipOnScreen: " + output);
+        if (null == output || "null".equalsIgnoreCase(output)) {
+            Log.i(LOG_TAG, "No PIP window is found");
+            return false;
+        }
+        // Note that ACTIVITY_PIPOVERLAY would disappear in seconds, afterwards the app playback
+        // overlay comes in. It's just safe to think of that whatever activity in pinned stack is
+        // PIP window.
+        return output.contains(activityName);
+    }
+
+    /**
+     * Setup expectations: None
+     * <p>
+     * Checks if a PIP window is shown on screen.
+     * </p>
+     * @param activityName the activity of the application that implements PIP playback
+     */
+    public boolean isInFullscreen(String activityName) {
+        String output = mCmdHelper.executeAmStackInfo(FULLSCREEN_WORKSPACE_STACK_ID);
+        Log.i(LOG_TAG, "isInFullscreen: " + output);
+        if (null == output || "null".equalsIgnoreCase(output)) {
+            Log.i(LOG_TAG, "Activity is not found in full screen: " + activityName);
+            return false;
+        }
+        return output.contains(activityName);
+    }
+
+    /**
+     * Setup expectations: None
+     * <p>
+     * Returns the bounds on screen for a PIP window.
+     * </p>
+     */
+    private Rect getPipBounds(String packageName, String activityName) {
+        return getBounds(PINNED_STACK_ID, packageName, activityName);
+    }
+
+    private Rect getBounds(int stackId, String packageName, String activityName) {
+        // Format:
+        // taskId=216: com.example.android.tvleanback/com.example.android.tvleanback.ui.PlaybackOverlayActivity bounds=[775,54][1145,262] ...
+        final Pattern BOUNDS_REGEX = Pattern.compile(
+                String.format("taskId=\\d+: %s/%s bounds=\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]",
+                        packageName, activityName));
+        String output = mCmdHelper.executeAmStackInfo(stackId);
+        Log.d(LOG_TAG, "getBounds output=" + output);
+        Matcher matcher = BOUNDS_REGEX.matcher(output);
+        if (matcher.find()) {
+            int left = Integer.parseInt(matcher.group(1));
+            int top = Integer.parseInt(matcher.group(2));
+            int right = Integer.parseInt(matcher.group(3));
+            int bottom = Integer.parseInt(matcher.group(4));
+            Log.i(LOG_TAG, String.format("Bounds found: [%d,%d][%d,%d] for %s/%s",
+                    left, top, right, bottom, packageName, activityName));
+            return new Rect(left, top, right, bottom);
+        }
+        Log.w(LOG_TAG, "getBounds returns null");
+        return null;
+    }
+
+    /**
+     * Setup expectations: PIP is open.
+     * <p>
+     * Moves the PIP window to full screen.
+     * </p>
+     */
+    public void executeCommandPipToFullscreen(String packageName, String activityName,
+            boolean throwIfFail) {
+        int taskId = getTaskId(packageName, activityName);
+        if (taskId != INVALID_TASK_ID) {
+            mCmdHelper.executeAmStackMovetask(taskId,
+                    FULLSCREEN_WORKSPACE_STACK_ID);
+        }
+        if (throwIfFail && isPipOnScreen(activityName)) {
+            throw new UnknownUiException("Failed to move a PIP window to fullscreen");
+        }
+    }
+
+    /**
+     * Get the current playback state for a given package that owns the media session.
+     * @param packageName the package name of media session owner
+     * @return
+     * 0 = PlaybackState.STATE_NONE
+     * 1 = PlaybackState.STATE_STOPPED
+     * 2 = PlaybackState.STATE_PAUSED
+     * 3 = PlaybackState.STATE_PLAYING
+     */
+    public int getPlaybackState(String packageName) {
+        String output = mCmdHelper.executeDumpsysMediaSession();
+        // Parse the output of dumpsys media_session.
+        // Example :
+        // LeanbackSampleApp com.example.android.tvleanback/LeanbackSampleApp
+        //   package=com.example.android.tvleanback
+        //   ...
+        //   state=PlaybackState {state=3, position=0, buffered position=0, speed=1.0, updated=...}
+        int playbackState = 0;
+        int index = output.indexOf(String.format("package=%s", packageName));
+        if (index == -1) {
+            Log.w(LOG_TAG, String.format("No media session found for the package: %s", packageName));
+            return playbackState;
+        }
+        final Pattern PLAYBACKSTATE_REGEX = Pattern.compile(
+                "\\s*state=PlaybackState \\{state=(\\d+),.*");
+        Matcher matcher = PLAYBACKSTATE_REGEX.matcher(output.substring(index));
+        if (matcher.find()) {
+            playbackState = Integer.parseInt(matcher.group(1));
+            Log.i(LOG_TAG, String.format("PlaybackState=%s package=%s", playbackState, packageName));
+        }
+        return playbackState;
+    }
+
+    /**
+     * Setup expectation: None. Check if PIP overlay is shown and focused.
+     */
+    private boolean isPipStateOverlay() {
+        // TODO
+        throw new UnsupportedOperationException("This method is not yet implemented.");
+    }
+
+    /**
+     * Setup expectation: None. Check if PIP menu is shown in center.
+     */
+    public boolean isPipStateMenu(String packageName, String activityName) {
+        return PIP_MENU_BOUNDS.equals(getPipBounds(packageName, activityName));
+    }
+
+    /**
+     * Setup expectation: None. Check if the PIP is shown in Recents with focus.
+     */
+    public boolean isPipStateRecentsFocused(String packageName, String activityName) {
+        return PIP_RECENTS_FOCUSED_BOUNDS.equals(getPipBounds(packageName, activityName));
+    }
+
+    /**
+     * Setup expectation: None. Check if the PIP is shown with Settings.
+     */
+    public boolean isPipStateSettings(String packageName, String activityName) {
+        return PIP_SETTINGS_BOUNDS.equals(getPipBounds(packageName, activityName));
+    }
+
+    /**
+     * Setup expectation: When the PIP is shown in Recents with focus.
+     * <p>
+     * Toggles the media play/pause button on screen.
+     * </p>
+     */
+    public void togglePipMediaControls() {
+        UiObject2 pause = mDevice.findObject(By.res(UI_PACKAGE, "button").desc("Pause"));
+        UiObject2 play = mDevice.findObject(By.res(UI_PACKAGE, "button").desc("Play"));
+        if (pause != null) {
+            pause.click();
+        } else if (play != null) {
+            play.click();
+        } else {
+            throw new UnknownUiException("No Play/Pause button found in PIP in Recents");
+        }
+        mDevice.waitForIdle();
+        mDevice.pressDPadCenter();
+    }
+
+    /**
+     * Setup expectation: When the PIP is shown in Recents with focus.
+     * <p>
+     * Clicks the full screen button on screen.
+     * </p>
+     */
+    public void selectPipToFullScreenButton() {
+        UiObject2 button = mDevice.wait(
+                Until.findObject(By.res(UI_PACKAGE, "button").desc("Full screen")),
+                SHORT_SLEEP_MS);
+        button.click();
+        mDevice.waitForIdle();
+        mDevice.pressDPadCenter();
+    }
+
+    /**
+     * Setup expectation: When the PIP is shown in Recents with focus.
+     * <p>
+     * Clicks the Close button on screen.
+     * </p>
+     */
+    public void selectPipCloseButton() {
+        UiObject2 button = mDevice.wait(
+                Until.findObject(By.res(UI_PACKAGE, "button").desc("Close PIP")),
+                SHORT_SLEEP_MS);
+        button.click();
+        mDevice.waitForIdle();
+        mDevice.pressDPadCenter();
+
+    }
+
+    /**
+     * Setup expectation: None.
+     * <p>
+     * Check if the PIP is shown in Recents without focus.
+     * </p>
+     */
+    public boolean isPipStateRecents(String packageName, String activityName) {
+        return PIP_RECENTS_BOUNDS.equals(getPipBounds(packageName, activityName));
+    }
+
+    private int getTaskId(String packageName, String activityName) {
+        int taskId = INVALID_TASK_ID;
+        final Pattern TASK_REGEX = Pattern.compile(
+                String.format("taskId=(\\d+): %s/%s", packageName, activityName));
+        Matcher matcher = TASK_REGEX.matcher(mCmdHelper.executeAmStackList());
+        if (matcher.find()) {
+            taskId = Integer.parseInt(matcher.group(1));
+            Log.i(LOG_TAG, String.format("TaskId found: %d for %s/%s",
+                    taskId, packageName, activityName));
+        }
+        return taskId;
+    }
+}
+
diff --git a/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/SysUiRecentsHelperImpl.java b/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/SysUiRecentsHelperImpl.java
new file mode 100644
index 0000000..0872955
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/SysUiRecentsHelperImpl.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2016 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.test.helpers.tv;
+
+import android.app.Instrumentation;
+import android.os.RemoteException;
+import android.platform.test.helpers.AbstractLeanbackAppHelper;
+import android.platform.test.helpers.DPadHelper;
+import android.platform.test.helpers.IRecentsHelper;
+import android.platform.test.helpers.exceptions.UiTimeoutException;
+import android.platform.test.helpers.exceptions.UnknownUiException;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+/**
+ * App helper implementation class for Recents activity in System UI
+ */
+public class SysUiRecentsHelperImpl extends AbstractLeanbackAppHelper implements IRecentsHelper {
+    private static final String LOG_TAG = SysUiRecentsHelperImpl.class.getSimpleName();
+    private static final String UI_PACKAGE = "com.android.systemui";
+
+    private static final long RECENTS_SELECTION_TIMEOUT = 5000;
+    private static final String TEXT_NO_ITEMS = "No recent items";
+
+    private DPadHelper mDPadHelper;
+
+
+    public SysUiRecentsHelperImpl(Instrumentation instrumentation) {
+        super(instrumentation);
+        mDPadHelper = DPadHelper.getInstance(instrumentation);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getPackage() {
+        return UI_PACKAGE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getLauncherName() {
+        throw new UnsupportedOperationException("This method is not supported for Recents");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void open() {
+        try {
+            mDevice.pressRecentApps();
+            mDevice.waitForIdle();
+        } catch (RemoteException ex) {
+            Log.e(LOG_TAG, ex.toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void exit() {
+        mDevice.pressHome();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void dismissInitialDialogs() {
+        // Nothing to do.
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void flingRecents(Direction dir) {
+        throw new UnsupportedOperationException("This method is not supported for Recents "
+                + "in leanback library");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clearAll() {
+        final int MAX_ATTEMPTS = 10;
+        int attempt = 0;
+        while (attempt < MAX_ATTEMPTS) {
+            if (dismissTask() == false) {
+                break;
+            }
+            ++attempt;
+            // Once all tasks are dismissed, it exits to Home screen
+            if (!isAppInForeground()) {
+                break;
+            }
+        }
+        Log.i(LOG_TAG, String.format("%d task(s) is dismissed.", attempt));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean hasContent() {
+        if (!isAppInForeground()) {
+            throw new IllegalStateException("Recents is not open.");
+        }
+        return (getTaskCountOnScreen() > 0);
+    }
+
+    /**
+     * @return True if there is no content and it shows the "No recent items" text on screen.
+     */
+    public boolean hasNoRecentItems() {
+        return mDevice.hasObject(By.text(TEXT_NO_ITEMS));
+    }
+
+    /**
+     * Setup expectations: The target application is open in Recents.
+     * <p>
+     * Selects a given application.
+     * </p>
+     * @return True if it selects a given application.
+     */
+    public boolean selectTask(String appName) {
+        boolean found = (findTask(appName) != null);
+        if (!found) {
+            Log.w(LOG_TAG, String.format("The application not found in Recents: %s", appName));
+        }
+        return found;
+    }
+
+    /**
+     * Setup expectations: "Recents" is open.
+     * @return the name for an application currently selected in Recents
+     */
+    public String getFocusedTaskName() {
+        UiObject2 taskView = mDevice.wait(Until.findObject(getTaskViewSelector()),
+                RECENTS_SELECTION_TIMEOUT);
+        if (taskView == null) {
+            throw new UiTimeoutException("No task view found in Recents");
+        }
+        return taskView.findObject(By.focused(true)).findObject(
+                By.res(UI_PACKAGE, "card_title_text")).getText();
+    }
+
+    /**
+     * Setup expectations: "Recents" is open.
+     * @return the number of tasks on the Recents screen. This may differ from the number of
+     * the actual tasks.
+     */
+    public int getTaskCountOnScreen() {
+        return mDevice.findObject(getTaskViewSelector()).getChildCount();
+    }
+
+    /**
+     * Returns a {@link BySelector} describing the task to be dismissed in Recents
+     * @return
+     */
+    private BySelector getTaskDismissSelector() {
+        // The text "Dismiss" appears only when the card is selected to be dismissed on leanback.
+        return By.pkg(UI_PACKAGE).focused(true)
+                .hasChild(By.res(UI_PACKAGE, "card_dismiss_text").text("Dismiss"));
+    }
+
+    /**
+     * Returns a {@link BySelector} describing the task view in Recents
+     * @return
+     */
+    private BySelector getTaskViewSelector() {
+        return By.res(UI_PACKAGE, "task_list");
+    }
+
+    /**
+     * Setup expectations: "Recents" is open. This method will dismiss a focused task in Recents.
+     * @return True if a task is dismissed
+     */
+    public boolean dismissTask() {
+        if (hasNoRecentItems()) {
+            Log.i(LOG_TAG, "No recent items found");
+            return false;
+        }
+
+        if (!mDevice.wait(Until.hasObject(getTaskViewSelector()), RECENTS_SELECTION_TIMEOUT)) {
+            throw new UnknownUiException("No task view found in Recents");
+        }
+        UiObject2 task = mDevice.findObject(getTaskDismissSelector());
+        if (task == null) {
+            // Select a task to be dismissed again by pressing the down key
+            mDevice.pressDPadDown();
+            task = mDevice.wait(Until.findObject(getTaskDismissSelector()),
+                    RECENTS_SELECTION_TIMEOUT);
+            if (task == null) {
+                throw new UnknownUiException("Dismiss button not found");
+            }
+        }
+        mDevice.pressDPadCenter();
+        // Confirm that the task is dismissed
+        return mDevice.wait(Until.gone(getTaskDismissSelector()), RECENTS_SELECTION_TIMEOUT);
+    }
+
+    private UiObject2 findTask(String appName) {
+        UiObject2 taskView = mDevice.wait(Until.findObject(getTaskViewSelector()),
+                RECENTS_SELECTION_TIMEOUT);
+        UiObject2 app;
+        final int MAX_ATTEMPTS = 10;
+        if ((app = findTask(taskView, appName, Direction.LEFT, MAX_ATTEMPTS)) != null) {
+            return app;
+        }
+        if ((app = findTask(taskView, appName, Direction.RIGHT, MAX_ATTEMPTS)) != null) {
+            return app;
+        }
+        return null;
+    }
+
+    private UiObject2 findTask(UiObject2 container, String appName, Direction direction,
+            int maxAttempts) {
+        UiObject2 focused = container.findObject(By.focused(true));
+        if (focused == null) {
+            throw new UnknownUiException("No focused item found in Recents");
+        }
+        String currentName = focused.findObject(By.res(UI_PACKAGE, "card_title_text")).getText();
+        String nextName;
+        int attempt = 0;
+        boolean found = false;
+        while (!(found = appName.equalsIgnoreCase(currentName)) && attempt++ < maxAttempts) {
+            mDPadHelper.pressDPad(direction);
+            nextName = container.findObject(By.focused(true)).findObject(
+                    By.res(UI_PACKAGE, "card_title_text")).getText();
+            if (currentName.equals(nextName)) {
+                // It reaches to the end in this direction
+                Log.d(LOG_TAG, String.format("%s not found in Recents until it reaches to the end",
+                        appName));
+                return null;
+            } else {
+                currentName = nextName;
+            }
+        }
+
+        if (found) {
+            return focused;
+        }
+        Log.d(LOG_TAG, String.format("%s not found in Recents by moving next %d times",
+                appName, maxAttempts));
+        return null;
+    }
+}
+
diff --git a/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/SysUiSettingsHelperImpl.java b/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/SysUiSettingsHelperImpl.java
new file mode 100644
index 0000000..b996c5e
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/sysui-app-helper/src/android/platform/test/helpers/tv/SysUiSettingsHelperImpl.java
@@ -0,0 +1,486 @@
+/*
+ * Copyright (C) 2016 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.test.helpers.tv;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.platform.test.helpers.AbstractLeanbackAppHelper;
+import android.platform.test.helpers.DPadHelper;
+import android.platform.test.helpers.exceptions.UiTimeoutException;
+import android.platform.test.helpers.exceptions.UnknownUiException;
+import android.provider.Settings;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+import java.util.regex.Pattern;
+
+
+/**
+ * App helper implementation class for TV Settings
+ */
+public class SysUiSettingsHelperImpl extends AbstractLeanbackAppHelper {
+    private static final String LOG_TAG = SysUiSettingsHelperImpl.class.getSimpleName();
+    private static final String UI_PACKAGE = "com.android.tv.settings";
+    private static final String ACTION_SETTINGS = Settings.ACTION_SETTINGS;
+    private static final String RES_PKG_ANDROID = "android";
+    private static final String RES_TITLE = "title";
+    private static final String RES_SUMMARY = "summary";
+    private static final long SHORT_SLEEP_MS = 3000;
+
+    public static final int SETTINGS_SYSTEM = 0;
+    public static final int SETTINGS_SECURE = 1;
+    public static final int SETTINGS_GLOBAL = 2;
+
+    private Context mContext;
+
+
+    public SysUiSettingsHelperImpl(Instrumentation instrumentation) {
+        super(instrumentation);
+        mDPadHelper = DPadHelper.getInstance(instrumentation);
+        mContext = instrumentation.getContext();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getPackage() {
+        return UI_PACKAGE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getLauncherName() {
+        throw new UnsupportedOperationException("This method is not supported for Settings");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void open() {
+        open(ACTION_SETTINGS, SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Setup expectation: On the launcher home screen.
+     * <p>
+     * Launches the desired application and wait for it to begin running before returning.
+     * </p>
+     * @param timeoutMs timeout in milliseconds to open an activity
+     */
+    public void open(String action, long timeoutMs) {
+        launchActivity(action);
+        if (timeoutMs > 0 && !waitForOpen(timeoutMs)) {
+            throw new UiTimeoutException(String.format("Timed out to open a target package %s:"
+                    + " %d(ms)", getPackage(), timeoutMs));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void exit() {
+        mDevice.pressHome();
+        mDevice.waitForIdle();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void dismissInitialDialogs() {
+        // Nothing to do.
+    }
+
+    /**
+     * Setup expectations: The Settings is open.
+     * <p>
+     * Selects the main Settings item by title text.
+     * </p>
+     * @param title the title string of the setting to find
+     * @return true if the setting that matches the name is open
+     */
+    public boolean clickSetting(String title) {
+        UiObject2 setting = findSettingByTitle(title);
+        if (setting == null) {
+            return false;
+        }
+        mDPadHelper.pressDPadCenterAndWait(Until.newWindow(), SHORT_SLEEP_MS);
+        return true;
+    }
+
+    /**
+     * Setup expectations: The Settings is open. Selects the main Settings item by summary text.
+     * @param summary the summary string of the setting to find
+     * @return true if the setting that matches the name is open
+     */
+    public boolean clickSettingBySummary(String summary) {
+        UiObject2 setting = findSettingBySummary(summary);
+        if (setting == null) {
+            return false;
+        }
+        mDPadHelper.pressDPadCenterAndWait(Until.newWindow(), SHORT_SLEEP_MS);
+        return true;
+    }
+
+    /**
+     * Setup expectations: The Settings is open.
+     * @param title the title string of the setting to find
+     * @return true if it finds {@link UiObject2} that has a given title text
+     */
+    public boolean hasSettingByTitle(String title) {
+        return (findSettingByTitle(title) != null);
+    }
+
+    /**
+     * Setup expectations: The Settings is open.
+     * @param summary the summary string of the setting to find
+     * @return true if it finds {@link UiObject2} that has a given summary text
+     */
+    public boolean hasSettingBySummary(String summary) {
+        return (findSettingBySummary(summary) != null);
+    }
+
+    /**
+     * Setup expectations: The Settings is open. Finds the setting that matches both
+     * a given title and summary
+     * @param title the title string of the setting to find
+     * @param summary the summary string of the setting to find
+     * @return true if it finds {@link UiObject2} that has both title and summary text passed.
+     */
+    public boolean hasSettingByTitleAndSummary(String title, String summary) {
+        return (findSettingByTitleAndSummary(title, summary) != null);
+    }
+
+    /**
+     * Setup expectations: The Settings is open.
+     * @param text the name of the setting to find
+     * @return true if it finds {@link UiObject2} that has a given text either in title or summary
+     */
+    public boolean hasSettingByTitleOrSummary(String text) {
+        return (findSettingByTitleOrSummary(text) != null);
+    }
+
+    /**
+     * Setup expectations: The Settings is open. Checks if the switch bar is turned on.
+     * @param title the name of the setting to check
+     * @return true if the setting is turned on
+     */
+    public boolean isSwitchBarOn(String title) {
+        return "ON".equals(getSwitchBarText(title));
+    }
+
+    /**
+     * Setup expectations: The Settings is open. Checks if the switch bar is turned off.
+     * @param title the name of the setting to check
+     * @return true if the setting is turned off
+     */
+    public boolean isSwitchBarOff(String title) {
+        return "OFF".equals(getSwitchBarText(title));
+    }
+
+    /**
+     * Setup expectations: The Accessibility Settings is open. Finds the preview text on screen.
+     * @return true if the preview text is displayed on screen.
+     */
+    public boolean hasPreviewText() {
+        return mDevice.hasObject(By.res(UI_PACKAGE, "preview_text"));
+    }
+
+    /**
+     * Setup expectations: The Settings is open.
+     * @return {@link UiObject2} of the current focused setting
+     */
+    public String getCurrentFocusedSettingTitle() {
+        return mDevice.wait(Until.findObject(By.focused(true)), SHORT_SLEEP_MS)
+                .findObject(By.res(RES_PKG_ANDROID, "title")).getText();
+    }
+
+    /**
+     * Setup expectations: The Settings is open. Returns the summary text of the selected Settings.
+     * @param title the name of the setting to get the summary text
+     * @return String of the summary text
+     */
+    public String getSummaryTextByTitle(String title) {
+        UiObject2 settings = findSettingByTitle(title);
+        return settings.findObject(By.res(RES_PKG_ANDROID, RES_SUMMARY)).getText();
+    }
+
+    /**
+     * Setup expectations: The Settings is open.
+     *
+     * Exit the guided settings by pressing BACK key a given times
+     * @param maxDepth The maximum depth to exit the guided settings. Should be greater than 0
+     * @return true if the Settings is closed.
+     */
+    public boolean goBackGuidedSettings(int maxDepth) {
+        if (maxDepth < 1) {
+            Log.w(LOG_TAG, "maxDepth should be greater than 0");
+            maxDepth = 1;
+        }
+        UiObject2 focused = mDevice.wait(Until.findObject(By.focused(true)), SHORT_SLEEP_MS);
+        if (focused == null) {
+            throw new IllegalStateException("No focused item is found");
+        }
+        while (maxDepth-- > 0) {
+            mDPadHelper.pressBack();
+            if (!waitForOpen(SHORT_SLEEP_MS)) {
+                Log.w(LOG_TAG, "Settings is closed.");
+                return false;
+            } else if (focused.equals(
+                    mDevice.wait(Until.findObject(By.focused(true)), SHORT_SLEEP_MS))) {
+                Log.w(LOG_TAG, "The focused is the same. Nothing happened in Settings?");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Setup expectations: On waiting for a guided setting to open.
+     * @param title the title string of the guided setting
+     * @param timeoutMs timeout in milliseconds to get the header title
+     * @return true if the guided setting that has a given title is open in timeout
+     */
+    public boolean waitForOpenGuidedSetting(String title, long timeoutMs) {
+        UiObject2 header = mDevice.wait(
+                Until.findObject(By.res(UI_PACKAGE, "decor_title").text(title)), timeoutMs);
+        return (header != null);
+    }
+
+    /**
+     * Setup expectations: The Settings is open.
+     * @return the title of the guided settings
+     */
+    private String getGuidedSettingTitle() {
+        UiObject2 header = mDevice.findObject(By.res(UI_PACKAGE, "decor_title"));
+        if (header == null) {
+            throw new UnknownUiException("Header text is not found");
+        }
+        return header.getText();
+    }
+
+    public String getStringSetting(int type, String name) {
+        switch (type) {
+            case SETTINGS_SYSTEM:
+                return Settings.System.getString(mContext.getContentResolver(), name);
+            case SETTINGS_GLOBAL:
+                return Settings.Global.getString(mContext.getContentResolver(), name);
+            case SETTINGS_SECURE:
+                return Settings.Secure.getString(mContext.getContentResolver(), name);
+        }
+        return "";
+    }
+
+    public int getIntSetting(int type, String name, int def) {
+        int value = getIntSetting(type, name);
+        return value != Integer.MIN_VALUE ? value : def;
+    }
+
+    public int getIntSetting(int type, String name) {
+        try {
+            switch (type) {
+                case SETTINGS_SYSTEM:
+                    return Settings.System.getInt(mContext.getContentResolver(), name);
+                case SETTINGS_GLOBAL:
+                    return Settings.Global.getInt(mContext.getContentResolver(), name);
+                case SETTINGS_SECURE:
+                    return Settings.Secure.getInt(mContext.getContentResolver(), name);
+            }
+        } catch (Settings.SettingNotFoundException e) {
+            Log.w(LOG_TAG, String.format("Settings not found name=%s, type=%d", name, type));
+        }
+        return Integer.MIN_VALUE;
+    }
+
+    public boolean isDeveloperOptionsEnabled() {
+        return getIntSetting(SETTINGS_GLOBAL, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
+                android.os.Build.TYPE.equals("eng") ? 1 : 0) == 1;
+    }
+
+    /**
+     * Setup expectations: PIN code activity is open. Set a new PIN code
+     * @param pinCode the PIN code of 4 digits
+     * @return true if a PIN code is set
+     */
+    public boolean setNewPinCode(String pinCode) {
+        return setPinCode("Set a new PIN", pinCode, Direction.DOWN);
+    }
+
+    public boolean reenterPinCode(String pinCode) {
+        return setPinCode("Re-enter new PIN", pinCode, Direction.DOWN);
+    }
+
+    public boolean enterPinCode(String pinCode) {
+        return setPinCode("Enter PIN", pinCode, Direction.DOWN);
+    }
+
+    protected BySelector getTitleSelector(String text) {
+        return By.res(RES_PKG_ANDROID, RES_TITLE).text(text);
+    }
+
+    protected BySelector getSummarySelector(String text) {
+        return By.res(RES_PKG_ANDROID, RES_SUMMARY).text(text);
+    }
+
+    /**
+     * Find the focused item in Settings that has a descendant matches the criteria.
+     * @param selector for a descendant of the setting to match.
+     * @param direction the direction to find, only accepts UP and DOWN.
+     * @return {@link UiObject2} of the focusable item that has a given descendant
+     */
+    private UiObject2 findSettingHasDescendant(BySelector selector, Direction direction) {
+        if (!isAppInForeground()) {
+            throw new IllegalStateException("Required to open the Settings ahead");
+        }
+        if (direction != Direction.DOWN && direction != Direction.UP) {
+            throw new IllegalArgumentException("Required to go either up or down to find rows");
+        }
+
+        UiObject2 currentFocused = mDevice.findObject(By.focused(true));
+        UiObject2 prevFocused = null;
+        UiObject2 found = null;
+        while (!currentFocused.equals(prevFocused)) {
+            if ((found = mDevice.findObject(By.focused(true).hasDescendant(selector, 3)))
+                    != null) {
+                return found;
+            }
+            if (direction == Direction.DOWN) {
+                mDevice.pressDPadDown();
+            } else if (direction == Direction.UP) {
+                mDevice.pressDPadUp();
+            }
+            prevFocused = currentFocused;
+            currentFocused = mDevice.findObject(By.focused(true));
+        }
+        Log.d(LOG_TAG, "Failed to find the item until it reaches the end.");
+        return found;
+    }
+
+    private String getSwitchBarText(String title) {
+        UiObject2 setting = findSettingByTitle(title);
+        return setting.findObject(By.res(RES_PKG_ANDROID, "switch_widget")).getText();
+    }
+
+    private UiObject2 findSettingByTitle(String title) {
+        return findSettingBySelector(getTitleSelector(title), true);
+    }
+
+    private UiObject2 findSettingBySummary(String summary) {
+        return findSettingBySelector(getSummarySelector(summary), true);
+    }
+
+    private UiObject2 findSettingByTitleAndSummary(String title, String summary) {
+        BySelector titleSelector = getTitleSelector(title);
+        BySelector summarySelector = getSummarySelector(summary);
+        UiObject2 setting;
+        while ((setting = findSettingHasDescendant(titleSelector, Direction.DOWN)) != null) {
+            if (setting.hasObject(summarySelector)) {
+                return setting;
+            }
+        }
+        while ((setting = findSettingHasDescendant(titleSelector, Direction.UP)) != null) {
+            if (setting.hasObject(summarySelector)) {
+                return setting;
+            }
+        }
+        return null;
+    }
+
+    private UiObject2 findSettingByTitleOrSummary(String text) {
+        final Pattern RES_REGEX = Pattern.compile(
+                String.format("%s:id/(%s|%s)", RES_PKG_ANDROID, RES_TITLE, RES_SUMMARY));
+        return findSettingBySelector(By.res(RES_REGEX).text(text), true);
+    }
+
+    private UiObject2 findSettingBySelector(BySelector selector, boolean throwIfFail) {
+        UiObject2 setting;
+        if ((setting = findSettingHasDescendant(selector, Direction.DOWN)) != null) {
+            return setting;
+        }
+        if ((setting = findSettingHasDescendant(selector, Direction.UP)) != null) {
+            return setting;
+        }
+        if (throwIfFail) {
+            throw new UnknownUiException(
+                    String.format("No focused setting matches a given selector: %s",
+                            selector.toString()));
+        }
+        return null;
+    }
+
+    private boolean setPinCode(String title, String pinCode, Direction direction) {
+        if (!isValidPinCode(pinCode)) {
+            throw new IllegalArgumentException("4 digits PIN code is valid. pinCode=" + pinCode);
+        }
+        if (direction != Direction.DOWN && direction != Direction.UP) {
+            throw new IllegalArgumentException("Either up or down is allowed");
+        }
+        if (!mDevice.wait(Until.hasObject(By.res(getPackage(), "title").text(title)),
+                SHORT_SLEEP_MS)) {
+            throw new IllegalStateException("The title for PIN code not found: " + title);
+        }
+
+        // the PIN number starts from 0 and increases by going down
+        for (char c : pinCode.toCharArray()) {
+            int number = c - '0';
+            // Note that the resource ID for the number changes by the direction to search
+            String resId = (number == 0) ? "current_number"
+                    : (direction == Direction.DOWN) ? "next_number" : "previous_number";
+            mDPadHelper.pressDPad(direction, number);
+            if (!mDevice.wait(
+                    Until.hasObject(By.res(getPackage(), resId).text(String.valueOf(c))),
+                    SHORT_SLEEP_MS)) {
+                throw new UnknownUiException("Couldn't find the number:" + c);
+            }
+            mDPadHelper.pressDPadCenter();  // Move next
+        }
+        return true;
+    }
+
+    private boolean isValidPinCode(String pinCode) {
+        final String PIN_CODE_FORMAT = "[0-9][0-9][0-9][0-9]";
+        return pinCode != null && pinCode.matches(PIN_CODE_FORMAT);
+    }
+
+    /**
+     * Setup expectations: None
+     *
+     * Starts the Settings activity
+     */
+    // TODO Move to a base or utility class that each test could access
+    private void launchActivity() {
+        launchActivity(ACTION_SETTINGS);
+    }
+
+    private void launchActivity(String action) {
+        Intent intent = new Intent(action);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        Log.d(LOG_TAG, "launchActivity intent=" + intent.toString());
+        mInstrumentation.getContext().startActivity(intent);
+    }
+}
diff --git a/libraries/first-party-app-helpers/tv/youtube-app-helper/Android.mk b/libraries/first-party-app-helpers/tv/youtube-app-helper/Android.mk
new file mode 100644
index 0000000..7c1d572
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/youtube-app-helper/Android.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := tv-youtube-app-helper
+LOCAL_JAVA_LIBRARIES := ub-uiautomator base-app-helpers
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
diff --git a/libraries/first-party-app-helpers/tv/youtube-app-helper/src/android/platform/test/helpers/tv/YouTubeHelperImpl.java b/libraries/first-party-app-helpers/tv/youtube-app-helper/src/android/platform/test/helpers/tv/YouTubeHelperImpl.java
new file mode 100644
index 0000000..3646402
--- /dev/null
+++ b/libraries/first-party-app-helpers/tv/youtube-app-helper/src/android/platform/test/helpers/tv/YouTubeHelperImpl.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2016 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.test.helpers.tv;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.os.SystemClock;
+import android.platform.test.helpers.AbstractLeanbackAppHelper;
+import android.platform.test.helpers.exceptions.UiTimeoutException;
+import android.platform.test.helpers.exceptions.UnknownUiException;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+
+
+public class YouTubeHelperImpl extends AbstractLeanbackAppHelper {
+
+    private static final String TAG = YouTubeHelperImpl.class.getSimpleName();
+    private static final String UI_PACKAGE = "com.google.android.youtube.tv";
+    private static final String RES_MAIN_ACTIVITY_ID = "top_layout";
+    private static final long SHORT_SLEEP_MS = 5000;    // 5 seconds
+    private static final long LONG_SLEEP_MS = 30000;    // 30 seconds
+    private static final long LOADING_CONTENT_TIMEOUT_MS = 5000;
+
+
+    public YouTubeHelperImpl(Instrumentation instrumentation) {
+        super(instrumentation);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getPackage() {
+        return UI_PACKAGE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getLauncherName() {
+        return "YouTube";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected BySelector getMainActivitySelector() {
+        return By.res(UI_PACKAGE, RES_MAIN_ACTIVITY_ID);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected BySelector getBrowseHeadersSelector() {
+        return By.res(UI_PACKAGE, "guide").hasChild(By.selected(true));
+    }
+
+    /**
+     * Selects search orb.
+     */
+    public void selectSearchOrb() {
+        returnToMainActivity();
+        UiObject2 searchOrb = null;
+
+        final int MAX_ATTEMPTS_SEARCH_ORB = 20;
+        int attempt = 0;
+        // Wait until the search orb appears at runtime.
+        while (attempt++ < MAX_ATTEMPTS_SEARCH_ORB) {
+            searchOrb = mDevice.wait(Until.findObject(
+                    By.res(UI_PACKAGE, "title_orb").clickable(true)), SHORT_SLEEP_MS);
+            if (searchOrb == null) {
+                // Search orb could be found at the top of activity
+                mDPadHelper.pressDPad(Direction.UP);
+                continue;
+            }
+        }
+        if (attempt == MAX_ATTEMPTS_SEARCH_ORB) {
+            throw new UnknownUiException("Failed to select search orb");
+        }
+        searchOrb.click();
+    }
+
+    /**
+     * Search for a given query text in YouTube app
+     */
+    public void search(String query) {
+        selectSearchOrb();
+
+        UiObject2 editText = mDevice.wait(
+                Until.findObject(By.res(UI_PACKAGE, "lb_search_text_editor")),
+                5 * 60 * 1000);
+        if (editText == null) {
+            throw new UnknownUiException("Search text editor not found");
+        }
+        if (!editText.isFocused()) {
+            Log.d(TAG, "Search text editor is getting focus");
+            mDevice.pressDPadRight();
+            SystemClock.sleep(SHORT_SLEEP_MS);
+        }
+        editText.setText(query);
+        mDevice.waitForIdle();
+        mDevice.pressEnter();
+        if (!waitForContentLoaded(SHORT_SLEEP_MS)) {
+            throw new UiTimeoutException(
+                    String.format("Failed to find the search results in %d (ms)", SHORT_SLEEP_MS));
+        }
+    }
+
+    /**
+     * Setup expectations: YouTube search result is open and the first result is focused.
+     *
+     * Open the first visible search result in the list and block until the search result
+     * comes in the foreground.
+     */
+    public void openFirstSearchResult() {
+        openSearchResultByIndex(0);
+    }
+
+    /**
+     * Setup expectations: YouTube search result is open and the first result is focused.
+     *
+     * Open the (index)'th visible search result in the list and block until the search result
+     * comes in the foreground.
+     */
+    public void openSearchResultByIndex(int index) {
+        if (!isInSearchPage()) {
+            throw new IllegalStateException("Must be in search page to select search results");
+        }
+        UiObject2 rowContent = mDevice.wait(Until.findObject(
+                By.res(UI_PACKAGE, "row_content")), SHORT_SLEEP_MS);
+        if (rowContent == null) {
+            throw new IllegalStateException("No search results found");
+        }
+
+        // Select a content by index
+        UiObject2 focused = rowContent.findObject(By.focused(true));
+        if (focused == null) {
+            throw new IllegalStateException("The search result is not selected");
+        }
+        UiObject2 current;
+        for (int i = 0; i < index; ++i) {
+            mDevice.pressDPadRight();
+            SystemClock.sleep(SHORT_SLEEP_MS);
+            current = rowContent.findObject(By.focused(true));
+            if (focused.equals(current)) {
+                Log.w(TAG, "openSearchResultByIndex: the index is out of bounds.");
+                break;
+            } else {
+                focused = current;
+            }
+        }
+        mDevice.pressDPadCenter();
+
+        // Wait until the content is open
+        if (!mDevice.wait(Until.gone(By.res(UI_PACKAGE, "lb_search_bar_items")),
+                LOADING_CONTENT_TIMEOUT_MS)) {
+            throw new UiTimeoutException("Opening search result timed out");
+        }
+    }
+
+    /**
+     * Setup expectations: Loading content in the app
+     *
+     * This method blocks until the content is loaded in a content row or a search row
+     *
+     * @param timeout wait timeout in milliseconds
+     * @return true if the content is loaded within timeout, false otherwise
+     */
+    public boolean waitForContentLoaded(long timeout) {
+        return mDevice.wait(
+                Until.hasObject(By.res(UI_PACKAGE, "row_content").hasChild(By.selected(true))),
+                timeout);
+    }
+
+    /**
+     * Setup expectations: Sign-in page is open.
+     *
+     * Selects the account to use if no account has been set up.
+     */
+    public boolean signIn(String account) {
+        if (!"Sign in".equals(getGuidanceTitleText())) {
+            throw new IllegalStateException("This method should be called in the Sign-in page.");
+        }
+        if (selectGuidedAction(account) == null) {
+            Log.e(TAG, String.format("No account matches: %s", account));
+            return false;
+        }
+        mDPadHelper.pressDPadCenter();
+        return mDevice.wait(Until.hasObject(getMainActivitySelector()), SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Setup expectations: On browse fragment. Sign out
+     */
+    public void signOut() {
+        openSettings();
+        if (!hasCardInRow("Sign out")) {
+            throw new UnknownUiException("Sign out is not found");
+        }
+        mDPadHelper.pressDPadCenter();
+        mDevice.wait(Until.findObject(By.res(getPackage(), "title_text").text("Sign in")),
+                SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Setup expectations: The main activity is open.
+     *
+     * Returns true if no user is signed in the app.
+     */
+    public boolean isNoUserSignedIn() {
+        // Some sections "Subscriptions", "History", "Purchases" are not available
+        // with no user signed in
+        final String[] SECTIONS_FOR_SIGNED_IN_USER = {"Subscriptions", "History", "Purchases"};
+        for (String section : SECTIONS_FOR_SIGNED_IN_USER) {
+            if (mDevice.hasObject(By.res(getPackage(), "row_header").text(section))) {
+                Log.d(TAG, "The section for a signed in user is found: " + section);
+                return false;
+            }
+        }
+
+        // Open Settings and confirm that the Sign-in card is shown
+        openSettings();
+        return hasCardInRow("Sign in");
+    }
+
+    /**
+     * Setup expectations: On browse fragment
+     *
+     * Returns the name of account currently signed in
+     */
+    public String getSignInUserName() {
+        openSettings();
+        return getCardContentText("Sign out");
+    }
+
+    private boolean isInSearchPage() {
+        return mDevice.hasObject(By.res(UI_PACKAGE, "search_fragment"));
+    }
+
+    /**
+     * @return true if YouTube plays a video in the foreground
+     */
+    public boolean isInVideoPlayback() {
+        return isInVideoPlayback(0);
+    }
+
+    private boolean isInVideoPlayback(long timeoutMs) {
+        if (!isAppInForeground()) {
+            Log.w(TAG, "YouTube was closed.");
+            return false;
+        }
+        return mDevice.wait(Until.hasObject(By.res(UI_PACKAGE, "watch_player")), timeoutMs);
+    }
+
+    /**
+     * Open the Popular on YouTube section
+     */
+    public void openPopularOnYouTube() {
+        openHeader("Popular on YouTube");
+    }
+
+    public void openHome() {
+        openHeader("Home");
+    }
+
+    public void openSettings() {
+        openHeader("Settings");
+    }
+
+    private UiObject2 getFocusedVideoCard() {
+        BySelector cardSelector = By.focused(true).hasChild(
+                By.res(getPackage(), "image_card"));
+        return mDevice.wait(Until.findObject(cardSelector), SHORT_SLEEP_MS);
+    }
+
+    /**
+     * Setup expectations: YouTube is open with a focused video.
+     * @return the duration in milliseconds of a focused video
+     */
+    public long getFocusedVideoDuration() {
+        UiObject2 card = getFocusedVideoCard();
+        if (card == null) {
+            throw new IllegalStateException("Could not find the video card");
+        }
+        // Get video length
+        UiObject2 length = card.findObject(By.res(getPackage(), "duration"));
+        if (length == null) {
+            throw new UnknownUiException("Could not find an object of video duration");
+        }
+        String durationText = length.getText();
+        if (durationText == null || "".equals(durationText)) {
+            throw new UnknownUiException("Could not find length of the selected video");
+        }
+
+        String formatString = (durationText.split(":").length == 3) ? "HH:mm:ss" : "mm:ss";
+        SimpleDateFormat format = new SimpleDateFormat(formatString);
+        format.setTimeZone(TimeZone.getTimeZone("GMT"));
+        long durationMs;
+        try {
+            durationMs = format.parse(length.getText()).getTime();
+            Log.d(TAG, String.format("Video length is %d in milliseconds", durationMs));
+        } catch (ParseException e) {
+            throw new RuntimeException(String.format("Failed to parse video length '%s'",
+                    length.getText()));
+        }
+        return durationMs;
+    }
+
+    /**
+     * Setup expectations: YouTube is open with a focused video.
+     * @return the title text of a focused video
+     */
+    public String getFocusedVideoTitleText() {
+        UiObject2 card = getFocusedVideoCard();
+        if (card == null) {
+            throw new IllegalStateException("Could not find the video card");
+        }
+        return card.findObject(By.res(getPackage(), "title_text")).getText();
+    }
+
+    /**
+     * Setup expectations: YouTube is open with a focused video.
+     * @return the content text of a focused video
+     */
+    public String getFocusedVideoContentText() {
+        UiObject2 card = getFocusedVideoCard();
+        if (card == null) {
+            throw new IllegalStateException("Could not find the video card");
+        }
+        return card.findObject(By.res(getPackage(), "content_text")).getText();
+    }
+
+    /**
+     * Setup expectations: YouTube is open with a focused video.
+     * @param timeoutMs Timeout in milliseconds to play a video. Set to 0 if it plays until the
+     *                  end.
+     * @return true if it plays without an error during a given duration.
+     */
+    public boolean playFocusedVideo(long timeoutMs) {
+        long durationMs = getFocusedVideoDuration();
+        Log.i(TAG, String.format("Playing a video for %d (ms)", timeoutMs));
+
+        // Play the video
+        mDevice.pressDPadCenter();
+        if (!isInVideoPlayback(SHORT_SLEEP_MS)) {
+            throw new IllegalStateException("Must be in video playback");
+        }
+
+        // Wait for the given duration
+        if (timeoutMs <= 0 || timeoutMs > durationMs) {
+            timeoutMs = durationMs;
+        }
+        SystemClock.sleep(timeoutMs);
+        return true;
+    }
+
+    // TODO Move to a base or utility class that each test could access.
+    public void launchActivity() {
+        Intent intent = mInstrumentation.getContext().getPackageManager()
+                .getLaunchIntentForPackage(UI_PACKAGE);
+        Log.d(TAG, "launchActivity intent=" + intent.toString());
+        mInstrumentation.getContext().startActivity(intent);
+    }
+}
diff --git a/libraries/launcher-helper/src/android/support/test/launcherhelper/LeanbackLauncherStrategy.java b/libraries/launcher-helper/src/android/support/test/launcherhelper/LeanbackLauncherStrategy.java
index db3b0ac..16c6b3b 100644
--- a/libraries/launcher-helper/src/android/support/test/launcherhelper/LeanbackLauncherStrategy.java
+++ b/libraries/launcher-helper/src/android/support/test/launcherhelper/LeanbackLauncherStrategy.java
@@ -641,8 +641,12 @@
         if (button == null) {
             throw new IllegalStateException("Restricted Profile not found on launcher");
         }
-        mDevice.pressDPadCenter();
-        mDevice.wait(Until.gone(getWorkspaceSelector()), APP_LAUNCH_TIMEOUT);
+        mDevice.performActionAndWait(new Runnable() {
+            @Override
+            public void run() {
+                mDevice.pressDPadCenter();
+            }
+        }, Until.newWindow(), APP_LAUNCH_TIMEOUT);
     }
 
     protected UiObject2 findSettingInRow(BySelector selector, Direction direction) {
diff --git a/tests/functional/tv/TvSysUiTests/AndroidManifest.xml b/tests/functional/tv/TvSysUiTests/AndroidManifest.xml
index 48a1cc0..be86f89 100644
--- a/tests/functional/tv/TvSysUiTests/AndroidManifest.xml
+++ b/tests/functional/tv/TvSysUiTests/AndroidManifest.xml
@@ -15,15 +15,16 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.test.functional.tv.sysui">
+    package="android.test.functional.tv.sysui"
+    android:sharedUserId="android.uid.system" >
+
+    <uses-sdk android:minSdkVersion="21"
+          android:targetSdkVersion="24"/>
 
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <uses-sdk android:minSdkVersion="21"
-          android:targetSdkVersion="24"/>
-
     <instrumentation
             android:name="android.support.test.runner.AndroidJUnitRunner"
             android:targetPackage="android.test.functional.tv.sysui"
diff --git a/tests/functional/tv/TvSysUiTests/src/android/test/functional/tv/common/SysUiTestBase.java b/tests/functional/tv/TvSysUiTests/src/android/test/functional/tv/common/SysUiTestBase.java
index dec64fe..e794d74 100644
--- a/tests/functional/tv/TvSysUiTests/src/android/test/functional/tv/common/SysUiTestBase.java
+++ b/tests/functional/tv/TvSysUiTests/src/android/test/functional/tv/common/SysUiTestBase.java
@@ -18,9 +18,19 @@
 
 import android.app.Instrumentation;
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.platform.test.helpers.CommandHelper;
 import android.platform.test.helpers.DPadHelper;
+import android.platform.test.helpers.tv.LeanbackDemoHelperImpl;
+import android.platform.test.helpers.tv.NoTouchAuthHelperImpl;
+import android.platform.test.helpers.tv.SearchHelperImpl;
+import android.platform.test.helpers.tv.SysUiPipHelperImpl;
+import android.platform.test.helpers.tv.SysUiRecentsHelperImpl;
+import android.platform.test.helpers.tv.SysUiSettingsHelperImpl;
+import android.platform.test.helpers.tv.YouTubeHelperImpl;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.launcherhelper.ILeanbackLauncherStrategy;
 import android.support.test.launcherhelper.LauncherStrategyFactory;
@@ -46,7 +56,15 @@
 
     protected CommandHelper mCmdHelper;
     protected DPadHelper mDPadHelper;
-    protected ILeanbackLauncherStrategy mLauncherStrategy;
+    protected LeanbackLauncherStrategy mLauncherStrategy;
+    protected LeanbackDemoHelperImpl mLeanbackDemoHelper;
+    protected NoTouchAuthHelperImpl mNoTouchAuthHelper;
+    protected SearchHelperImpl mSearchHelper;
+    protected SysUiPipHelperImpl mPipHelper;
+    protected SysUiRecentsHelperImpl mRecentsHelper;
+    protected SysUiSettingsHelperImpl mSettingsHelper;
+    protected YouTubeHelperImpl mYouTubeHelper;
+
 
     public SysUiTestBase() {
         initialize(InstrumentationRegistry.getInstrumentation());
@@ -71,6 +89,13 @@
         }
         mCmdHelper = new CommandHelper(getInstrumentation());
         mDPadHelper = DPadHelper.getInstance(getInstrumentation());
+        mLeanbackDemoHelper = new LeanbackDemoHelperImpl(getInstrumentation());
+        mNoTouchAuthHelper = new NoTouchAuthHelperImpl(getInstrumentation());
+        mPipHelper = new SysUiPipHelperImpl(getInstrumentation());
+        mRecentsHelper = new SysUiRecentsHelperImpl(getInstrumentation());
+        mSearchHelper = new SearchHelperImpl(getInstrumentation());
+        mSettingsHelper = new SysUiSettingsHelperImpl(getInstrumentation());
+        mYouTubeHelper = new YouTubeHelperImpl(getInstrumentation());
     }
 
     protected Instrumentation getInstrumentation() {
@@ -102,4 +127,23 @@
         }
         return defaultValue;
     }
+
+    protected static boolean isRestrictedUser(Context context) {
+        UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        UserInfo userInfo = userManager.getUserInfo(UserHandle.myUserId());
+        Log.d(TAG, "isRestrictedUser? " + (userInfo.isRestricted() ? "Y" : "N"));
+        return userInfo.isRestricted();
+    }
+
+    protected static boolean hasRestrictedUser(Context context) {
+        UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        for (UserInfo userInfo : userManager.getUsers()) {
+            if (userInfo.isRestricted()) {
+                Log.d(TAG, "hasRestrictedUser? Y");
+                return true;
+            }
+        }
+        Log.d(TAG, "hasRestrictedUser? N");
+        return false;
+    }
 }
