/*
 * 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 com.android.cts.usepermission;

import static junit.framework.Assert.assertEquals;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import android.Manifest;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.icu.text.CaseMap;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
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.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.util.ArrayMap;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.ScrollView;

import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.runner.RunWith;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;
import java.util.regex.Pattern;

@RunWith(AndroidJUnit4.class)
public abstract class BasePermissionsTest {
    private static final String PLATFORM_PACKAGE_NAME = "android";

    private static final long IDLE_TIMEOUT_MILLIS = 1000;
    private static final long GLOBAL_TIMEOUT_MILLIS = 10000;

    private static final long RETRY_TIMEOUT = 10 * GLOBAL_TIMEOUT_MILLIS;
    private static final String LOG_TAG = "BasePermissionsTest";

    private static Map<String, String> sPermissionToLabelResNameMap = new ArrayMap<>();

    private Context mContext;
    private Resources mPlatformResources;
    private boolean mWatch;

    protected static Instrumentation getInstrumentation() {
        return InstrumentationRegistry.getInstrumentation();
    }

    protected static void assertPermissionRequestResult(BasePermissionActivity.Result result,
            int requestCode, String[] permissions, boolean[] granted) {
        assertEquals(requestCode, result.requestCode);
        for (int i = 0; i < permissions.length; i++) {
            assertEquals(permissions[i], result.permissions[i]);
            assertEquals(granted[i] ? PackageManager.PERMISSION_GRANTED
                    : PackageManager.PERMISSION_DENIED, result.grantResults[i]);

        }
    }

    protected static UiDevice getUiDevice() {
        return UiDevice.getInstance(getInstrumentation());
    }

    protected static Activity launchActivity(String packageName,
            Class<?> clazz, Bundle extras) {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setClassName(packageName, clazz.getName());
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (extras != null) {
            intent.putExtras(extras);
        }
        Activity activity = getInstrumentation().startActivitySync(intent);
        getInstrumentation().waitForIdleSync();

        return activity;
    }

    private void initPermissionToLabelMap(boolean permissionReviewMode) {
        if (!permissionReviewMode) {
            // Contacts
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CONTACTS, "@android:string/permgrouplab_contacts");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CONTACTS, "@android:string/permgrouplab_contacts");
            // Calendar
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CALENDAR, "@android:string/permgrouplab_calendar");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CALENDAR, "@android:string/permgrouplab_calendar");
            // SMS
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.SEND_SMS, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_SMS, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_SMS, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_WAP_PUSH, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_MMS, "@android:string/permgrouplab_sms");
            sPermissionToLabelResNameMap.put(
                    "android.permission.READ_CELL_BROADCASTS", "@android:string/permgrouplab_sms");
            // Storage
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    "@android:string/permgrouplab_storage");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    "@android:string/permgrouplab_storage");
            // Location
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    "@android:string/permgrouplab_location");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    "@android:string/permgrouplab_location");
            // Phone
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_PHONE_STATE, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.CALL_PHONE, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    "android.permission.ACCESS_IMS_CALL_SERVICE",
                    "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CALL_LOG, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CALL_LOG, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ADD_VOICEMAIL, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.USE_SIP, "@android:string/permgrouplab_phone");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.PROCESS_OUTGOING_CALLS,
                    "@android:string/permgrouplab_phone");
            // Microphone
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECORD_AUDIO, "@android:string/permgrouplab_microphone");
            // Camera
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.CAMERA, "@android:string/permgrouplab_camera");
            // Body sensors
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.BODY_SENSORS, "@android:string/permgrouplab_sensors");
        } else {
            // Contacts
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CONTACTS, "@android:string/permlab_readContacts");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CONTACTS, "@android:string/permlab_writeContacts");
            // Calendar
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CALENDAR, "@android:string/permgrouplab_calendar");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CALENDAR, "@android:string/permgrouplab_calendar");
            // SMS
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.SEND_SMS, "@android:string/permlab_sendSms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_SMS, "@android:string/permlab_receiveSms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_SMS, "@android:string/permlab_readSms");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_WAP_PUSH, "@android:string/permlab_receiveWapPush");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECEIVE_MMS, "@android:string/permlab_receiveMms");
            sPermissionToLabelResNameMap.put(
                    "android.permission.READ_CELL_BROADCASTS",
                    "@android:string/permlab_readCellBroadcasts");
            // Storage
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    "@android:string/permgrouplab_storage");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    "@android:string/permgrouplab_storage");
            // Location
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    "@android:string/permgrouplab_location");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    "@android:string/permgrouplab_location");
            // Phone
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_PHONE_STATE, "@android:string/permlab_readPhoneState");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.CALL_PHONE, "@android:string/permlab_callPhone");
            sPermissionToLabelResNameMap.put(
                    "android.permission.ACCESS_IMS_CALL_SERVICE",
                    "@android:string/permlab_accessImsCallService");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.READ_CALL_LOG, "@android:string/permlab_readCallLog");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.WRITE_CALL_LOG, "@android:string/permlab_writeCallLog");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.ADD_VOICEMAIL, "@android:string/permlab_addVoicemail");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.USE_SIP, "@android:string/permlab_use_sip");
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.PROCESS_OUTGOING_CALLS,
                    "@android:string/permlab_processOutgoingCalls");
            // Microphone
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.RECORD_AUDIO, "@android:string/permgrouplab_microphone");
            // Camera
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.CAMERA, "@android:string/permgrouplab_camera");
            // Body sensors
            sPermissionToLabelResNameMap.put(
                    Manifest.permission.BODY_SENSORS, "@android:string/permgrouplab_sensors");
        }
    }

    @Before
    public void beforeTest() {
        mContext = InstrumentationRegistry.getTargetContext();
        try {
            Context platformContext = mContext.createPackageContext(PLATFORM_PACKAGE_NAME, 0);
            mPlatformResources = platformContext.getResources();
        } catch (PackageManager.NameNotFoundException e) {
            /* cannot happen */
        }

        PackageManager packageManager = mContext.getPackageManager();
        mWatch = packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH);
        initPermissionToLabelMap(packageManager.arePermissionsIndividuallyControlled());

        UiObject2 button = getUiDevice().findObject(By.text("Close"));
        if (button != null) {
            button.click();
        }
    }

    protected BasePermissionActivity.Result requestPermissions(
            String[] permissions, int requestCode, Class<?> clazz, Runnable postRequestAction)
            throws Exception {
        // Start an activity
        BasePermissionActivity activity = (BasePermissionActivity) launchActivity(
                getInstrumentation().getTargetContext().getPackageName(), clazz, null);

        activity.waitForOnCreate();

        // Request the permissions
        activity.requestPermissions(permissions, requestCode);

        // Define a more conservative idle criteria
        getInstrumentation().getUiAutomation().waitForIdle(
                IDLE_TIMEOUT_MILLIS, GLOBAL_TIMEOUT_MILLIS);

        // Perform the post-request action
        if (postRequestAction != null) {
            postRequestAction.run();
        }

        BasePermissionActivity.Result result = activity.getResult();
        activity.finish();
        return result;
    }

    protected void clickAllowButton() throws Exception {
        scrollToBottomIfWatch();
        waitForIdle();
        getUiDevice().wait(Until.findObject(By.res(
                "com.android.permissioncontroller:id/permission_allow_button")),
                GLOBAL_TIMEOUT_MILLIS).click();
    }

    protected void clickAllowAlwaysButton() throws Exception {
        waitForIdle();
        getUiDevice().wait(Until.findObject(By.res(
                "com.android.permissioncontroller:id/permission_allow_always_button")),
                GLOBAL_TIMEOUT_MILLIS).click();
    }

    protected void clickAllowForegroundButton() throws Exception {
        waitForIdle();
        getUiDevice().wait(Until.findObject(By.res(
                "com.android.permissioncontroller:id/permission_allow_foreground_only_button")),
                GLOBAL_TIMEOUT_MILLIS).click();
    }

    protected void clickDenyButton() throws Exception {
        scrollToBottomIfWatch();
        waitForIdle();
        getUiDevice().wait(Until.findObject(By.res(
                "com.android.permissioncontroller:id/permission_deny_button")),
                GLOBAL_TIMEOUT_MILLIS).click();
    }

    protected void clickDenyAndDontAskAgainButton() throws Exception {
        waitForIdle();
        getUiDevice().wait(Until.findObject(By.res(
                "com.android.permissioncontroller:id/permission_deny_and_dont_ask_again_button")),
                GLOBAL_TIMEOUT_MILLIS).click();
    }

    protected void clickDontAskAgainButton() throws Exception {
        scrollToBottomIfWatch();
        waitForIdle();
        getUiDevice().wait(Until.findObject(By.res(
                "com.android.permissioncontroller:id/permission_deny_dont_ask_again_button")),
                GLOBAL_TIMEOUT_MILLIS).click();
    }

    protected void grantPermission(String permission) throws Exception {
        grantPermissions(new String[]{permission});
    }

    protected void grantPermissions(String[] permissions) throws Exception {
        setPermissionGrantState(permissions, true, false);
    }

    protected void revokePermission(String permission) throws Exception {
        revokePermissions(new String[] {permission}, false);
    }

    protected void revokePermissions(String[] permissions, boolean legacyApp) throws Exception {
        setPermissionGrantState(permissions, false, legacyApp);
    }

    private void scrollToBottomIfWatch() throws Exception {
        if (mWatch) {
            getUiDevice().wait(Until.findObject(By.clazz(ScrollView.class)), GLOBAL_TIMEOUT_MILLIS);
            UiScrollable scrollable =
                    new UiScrollable(new UiSelector().className(ScrollView.class));
            if (scrollable.exists()) {
                scrollable.flingToEnd(10);
            }
        }
    }

    private void setPermissionGrantState(String[] permissions, boolean granted,
            boolean legacyApp) throws Exception {
        getUiDevice().pressBack();
        waitForIdle();
        getUiDevice().pressBack();
        waitForIdle();
        getUiDevice().pressBack();
        waitForIdle();

        if (isTv()) {
            getUiDevice().pressHome();
            waitForIdle();
        }

        // Open the app details settings
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setData(Uri.parse("package:" + mContext.getPackageName()));
        startActivity(intent);

        waitForIdle();

        // Open the permissions UI
        String label = mContext.getResources().getString(R.string.Permissions);
        AccessibilityNodeInfo permLabelView = getNodeTimed(() -> findByText(label), true);
        Assert.assertNotNull("Permissions label should be present", permLabelView);

        AccessibilityNodeInfo permItemView = findCollectionItem(permLabelView);

        click(permItemView);

        waitForIdle();

        for (String permission : permissions) {
            // Find the permission screen
            String permissionLabel = getPermissionLabel(permission);

            UiObject2 permissionView = null;
            long start = System.currentTimeMillis();
            while (permissionView == null && start + RETRY_TIMEOUT > System.currentTimeMillis()) {
                permissionView = getUiDevice().wait(Until.findObject(By.text(permissionLabel)),
                        IDLE_TIMEOUT_MILLIS);

                if (permissionView == null) {
                    getUiDevice().findObject(By.scrollable(true))
                            .scroll(Direction.DOWN, 1);
                }
            }

            permissionView.click();
            waitForIdle();

            String denyLabel = mContext.getResources().getString(R.string.Deny);

            final boolean wasGranted = !getUiDevice().wait(Until.findObject(By.text(denyLabel)),
                    GLOBAL_TIMEOUT_MILLIS).isChecked();
            if (granted != wasGranted) {
                // Toggle the permission

                if (granted) {
                    String allowLabel = mContext.getResources().getString(R.string.Allow);
                    getUiDevice().findObject(By.text(allowLabel)).click();
                } else {
                    getUiDevice().findObject(By.text(denyLabel)).click();
                }
                waitForIdle();

                if (wasGranted && legacyApp) {
                    scrollToBottomIfWatch();
                    Context context = getInstrumentation().getContext();
                    String packageName = context.getPackageManager()
                            .getPermissionControllerPackageName();
                    String resIdName = "com.android.permissioncontroller"
                            + ":string/grant_dialog_button_deny_anyway";
                    Resources resources = context
                            .createPackageContext(packageName, 0).getResources();
                    final int confirmResId = resources.getIdentifier(resIdName, null, null);
                    String confirmTitle = CaseMap.toUpper().apply(
                            resources.getConfiguration().getLocales().get(0),
                            resources.getString(confirmResId));
                    getUiDevice().wait(Until.findObject(
                            byTextStartsWithCaseInsensitive(confirmTitle)),
                            GLOBAL_TIMEOUT_MILLIS).click();

                    waitForIdle();
                }
            }

            getUiDevice().pressBack();
            waitForIdle();
        }

        getUiDevice().pressBack();
        waitForIdle();
        getUiDevice().pressBack();
        waitForIdle();
    }

    private BySelector byTextStartsWithCaseInsensitive(String prefix) {
        return By.text(Pattern.compile(String.format("(?i)^%s.*$", Pattern.quote(prefix))));
    }

    private String getPermissionLabel(String permission) throws Exception {
        String labelResName = sPermissionToLabelResNameMap.get(permission);
        assertNotNull("Unknown permisison " + permission, labelResName);
        final int resourceId = mPlatformResources.getIdentifier(labelResName, null, null);
        return mPlatformResources.getString(resourceId);
    }

    private void startActivity(final Intent intent) throws Exception {
        getInstrumentation().getUiAutomation().executeAndWaitForEvent(
                () -> {
            try {
                getInstrumentation().getContext().startActivity(intent);
            } catch (Exception e) {
                Log.e(LOG_TAG, "Cannot start activity: " + intent, e);
                fail("Cannot start activity: " + intent);
            }
        }, (AccessibilityEvent event) -> event.getEventType()
                        == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
         , GLOBAL_TIMEOUT_MILLIS);
    }

    private AccessibilityNodeInfo findByText(String text) throws Exception {
        AccessibilityNodeInfo root = getInstrumentation().getUiAutomation().getRootInActiveWindow();
        AccessibilityNodeInfo result = findByText(root, text);
        if (result != null) {
            return result;
        }
        return findByTextInCollection(root, text);
    }

    private static AccessibilityNodeInfo findByText(AccessibilityNodeInfo root, String text) {
        List<AccessibilityNodeInfo> nodes = root.findAccessibilityNodeInfosByText(text);
        for (AccessibilityNodeInfo node : nodes) {
            if (node.getText().toString().equals(text)) {
                return node;
            }
        }
        return null;
    }

    private static AccessibilityNodeInfo findByTextInCollection(AccessibilityNodeInfo root,
            String text)  throws Exception {
        AccessibilityNodeInfo result;
        final int childCount = root.getChildCount();
        for (int i = 0; i < childCount; i++) {
            AccessibilityNodeInfo child = root.getChild(i);
            if (child == null) {
                continue;
            }
            if (child.getCollectionInfo() != null) {
                scrollTop(child);
                result = getNodeTimed(() -> findByText(child, text), false);
                if (result != null) {
                    return result;
                }
                try {
                    while (child.getActionList().contains(
                            AccessibilityAction.ACTION_SCROLL_FORWARD) || child.getActionList()
                            .contains(AccessibilityAction.ACTION_SCROLL_DOWN)) {
                        scrollForward(child);
                        result = getNodeTimed(() -> findByText(child, text), false);
                        if (result != null) {
                            return result;
                        }
                    }
                } catch (TimeoutException e) {
                     /* ignore */
                }
            } else {
                result = findByTextInCollection(child, text);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

    private static void scrollTop(AccessibilityNodeInfo node) throws Exception {
        try {
            while (node.getActionList().contains(AccessibilityAction.ACTION_SCROLL_BACKWARD)) {
                scroll(node, false);
            }
        } catch (TimeoutException e) {
            /* ignore */
        }
    }

    private static void scrollForward(AccessibilityNodeInfo node) throws Exception {
            scroll(node, true);
    }

    private static void scroll(AccessibilityNodeInfo node, boolean forward) throws Exception {
        getInstrumentation().getUiAutomation().executeAndWaitForEvent(
                () -> {
                    if (isTv()) {
                        if (forward) {
                            getUiDevice().pressDPadDown();
                        } else {
                            for (int i = 0; i < 50; i++) {
                                getUiDevice().pressDPadUp();
                            }
                        }
                    } else {
                        node.performAction(forward
                                ? AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
                                : AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
                    }
                },
                (AccessibilityEvent event) -> event.getEventType()
                        == AccessibilityEvent.TYPE_VIEW_SCROLLED
                        || event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
                GLOBAL_TIMEOUT_MILLIS);
        node.refresh();
        waitForIdle();
    }

    private static void click(AccessibilityNodeInfo node) throws Exception {
        getInstrumentation().getUiAutomation().executeAndWaitForEvent(
                () -> node.performAction(AccessibilityNodeInfo.ACTION_CLICK),
                (AccessibilityEvent event) -> event.getEventType()
                        == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
                        || event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED,
                GLOBAL_TIMEOUT_MILLIS);
    }

    private static AccessibilityNodeInfo findCollectionItem(AccessibilityNodeInfo current)
            throws Exception {
        AccessibilityNodeInfo result = current;
        while (result != null) {
            // Nodes that are in the hierarchy but not yet on screen may not have collection item
            // info populated. Use a parent with collection info as an indicator in those cases.
            if (result.getCollectionItemInfo() != null || hasCollectionAsParent(result)) {
                return result;
            }
            result = result.getParent();
        }
        return null;
    }

    private static boolean hasCollectionAsParent(AccessibilityNodeInfo node) {
        return node.getParent() != null && node.getParent().getCollectionInfo() != null;
    }

    private static AccessibilityNodeInfo getNodeTimed(
            Callable<AccessibilityNodeInfo> callable, boolean retry) throws Exception {
        final long startTimeMillis = SystemClock.uptimeMillis();
        while (true) {
            try {
                AccessibilityNodeInfo node = callable.call();

                if (node != null) {
                    return node;
                }
            } catch (NullPointerException e) {
                Log.e(LOG_TAG, "NPE while finding AccessibilityNodeInfo", e);
            }

            final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
            if (!retry || elapsedTimeMillis > RETRY_TIMEOUT) {
                return null;
            }
            SystemClock.sleep(2 * elapsedTimeMillis);
        }
    }

    private static void waitForIdle() throws TimeoutException {
        getInstrumentation().getUiAutomation().waitForIdle(IDLE_TIMEOUT_MILLIS,
                GLOBAL_TIMEOUT_MILLIS);
    }

    private static boolean isTv() {
        return getInstrumentation().getContext().getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_LEANBACK);
    }
 }
