118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/*
218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Copyright (C) 2012 The Android Open Source Project
318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu *
418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License");
518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * you may not use this file except in compliance with the License.
618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You may obtain a copy of the License at
718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu *
818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu *      http://www.apache.org/licenses/LICENSE-2.0
918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu *
1018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Unless required by applicable law or agreed to in writing, software
1118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS,
1218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See the License for the specific language governing permissions and
1418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * limitations under the License.
1518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */
1618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
1718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupackage com.android.uiautomator.core;
1818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
1918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.app.UiAutomation;
2018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.app.UiAutomation.AccessibilityEventFilter;
2118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.graphics.Point;
2218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.Build;
2318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.Environment;
2418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.RemoteException;
2518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.SystemClock;
2618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.util.DisplayMetrics;
2718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.util.Log;
2818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.Display;
2918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.KeyEvent;
3018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.Surface;
3118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.accessibility.AccessibilityEvent;
3218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.accessibility.AccessibilityNodeInfo;
3318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
3418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.io.File;
3518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.ArrayList;
3618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.HashMap;
3718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.List;
3818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.concurrent.TimeoutException;
3918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
4018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/**
4118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * UiDevice provides access to state information about the device.
4218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You can also use this class to simulate user actions on the device,
4318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * such as pressing the d-pad or pressing the Home and Menu buttons.
4418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16
453fb03313e9d0e41f7c14b648c0f4dcfdab78bff3Allen Hair * @deprecated New tests should be written using UI Automator 2.0 which is available as part of the
463fb03313e9d0e41f7c14b648c0f4dcfdab78bff3Allen Hair * Android Testing Support Library.
4718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */
483fb03313e9d0e41f7c14b648c0f4dcfdab78bff3Allen Hair@Deprecated
4918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupublic class UiDevice {
5018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private static final String LOG_TAG = UiDevice.class.getSimpleName();
5118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
5218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    // Sometimes HOME and BACK key presses will generate no events if already on
5318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    // home page or there is nothing to go back to, Set low timeouts.
5418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private static final long KEY_PRESS_EVENT_TIMEOUT = 1 * 1000;
5518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
5618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    // store for registered UiWatchers
5718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private final HashMap<String, UiWatcher> mWatchers = new HashMap<String, UiWatcher>();
5818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private final List<String> mWatchersTriggers = new ArrayList<String>();
5918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
6018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    // remember if we're executing in the context of a UiWatcher
6118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private boolean mInWatcherContext = false;
6218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
6318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    // provides access the {@link QueryController} and {@link InteractionController}
6418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private UiAutomatorBridge mUiAutomationBridge;
6518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
6618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    // reference to self
6718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private static UiDevice sDevice;
6818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
6918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private UiDevice() {
7018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        /* hide constructor */
7118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
7218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
7318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
7418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @hide
7518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
7618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void initialize(UiAutomatorBridge uiAutomatorBridge) {
7718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        mUiAutomationBridge = uiAutomatorBridge;
7818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
7918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
8018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    boolean isInWatcherContext() {
8118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mInWatcherContext;
8218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
8318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
8418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
8518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Provides access the {@link QueryController} and {@link InteractionController}
8618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return {@link ShellUiAutomatorBridge}
8718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
8818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    UiAutomatorBridge getAutomatorBridge() {
8918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (mUiAutomationBridge == null) {
9018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            throw new RuntimeException("UiDevice not initialized");
9118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
9218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mUiAutomationBridge;
9318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
9418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
9518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
9618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Enables or disables layout hierarchy compression.
9718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
9818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * If compression is enabled, the layout hierarchy derived from the Acessibility
9918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * framework will only contain nodes that are important for uiautomator
10018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * testing. Any unnecessary surrounding layout nodes that make viewing
10118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * and searching the hierarchy inefficient are removed.
10218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
10318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param compressed true to enable compression; else, false to disable
10418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 18
10518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
10618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void setCompressedLayoutHeirarchy(boolean compressed) {
10718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        getAutomatorBridge().setCompressedLayoutHierarchy(compressed);
10818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
10918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
11018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
11118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Retrieves a singleton instance of UiDevice
11218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
11318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return UiDevice instance
11418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
11518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
11618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public static UiDevice getInstance() {
11718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (sDevice == null) {
11818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            sDevice = new UiDevice();
11918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
12018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return sDevice;
12118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
12218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
12318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
12418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Returns the display size in dp (device-independent pixel)
12518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
12618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * The returned display size is adjusted per screen rotation. Also this will return the actual
12718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * size of the screen, rather than adjusted per system decorations (like status bar).
12818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
12918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return a Point containing the display size in dp
13018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
13118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public Point getDisplaySizeDp() {
13218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
13318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Display display = getAutomatorBridge().getDefaultDisplay();
13418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Point p = new Point();
13518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        display.getRealSize(p);
13618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        DisplayMetrics metrics = new DisplayMetrics();
13718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        display.getRealMetrics(metrics);
13818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        float dpx = p.x / metrics.density;
13918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        float dpy = p.y / metrics.density;
14018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        p.x = Math.round(dpx);
14118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        p.y = Math.round(dpy);
14218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return p;
14318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
14418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
14518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
14618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Retrieves the product name of the device.
14718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
14818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * This method provides information on what type of device the test is running on. This value is
14918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * the same as returned by invoking #adb shell getprop ro.product.name.
15018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
15118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return product name of the device
15218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 17
15318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
15418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public String getProductName() {
15518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
15618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return Build.PRODUCT;
15718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
15818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
15918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
16018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Retrieves the text from the last UI traversal event received.
16118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
16218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * You can use this method to read the contents in a WebView container
16318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * because the accessibility framework fires events
16418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * as each text is highlighted. You can write a test to perform
16518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * directional arrow presses to focus on different elements inside a WebView,
16618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * and call this method to get the text from each traversed element.
16718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * If you are testing a view container that can return a reference to a
16818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Document Object Model (DOM) object, your test should use the view's
16918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * DOM instead.
17018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
17118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return text of the last traversal event, else return an empty string
17218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
17318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
17418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public String getLastTraversedText() {
17518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
17618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getQueryController().getLastTraversedText();
17718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
17818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
17918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
18018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Clears the text from the last UI traversal event.
18118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * See {@link #getLastTraversedText()}.
18218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
18318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
18418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void clearLastTraversedText() {
18518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
18618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        getAutomatorBridge().getQueryController().clearLastTraversedText();
18718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
18818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
18918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
19018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the MENU button.
19118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
19218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
19318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
19418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressMenu() {
19518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
19618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
19718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
19818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                KeyEvent.KEYCODE_MENU, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
19918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                KEY_PRESS_EVENT_TIMEOUT);
20018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
20118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
20218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
20318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the BACK button.
20418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
20518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
20618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
20718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressBack() {
20818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
20918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
21018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
21118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                KeyEvent.KEYCODE_BACK, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
21218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                KEY_PRESS_EVENT_TIMEOUT);
21318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
21418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
21518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
21618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the HOME button.
21718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
21818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
21918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
22018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressHome() {
22118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
22218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
22318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
22418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                KeyEvent.KEYCODE_HOME, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
22518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                KEY_PRESS_EVENT_TIMEOUT);
22618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
22718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
22818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
22918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the SEARCH button.
23018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
23118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
23218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
23318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressSearch() {
23418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
23518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return pressKeyCode(KeyEvent.KEYCODE_SEARCH);
23618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
23718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
23818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
23918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the CENTER button.
24018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
24118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
24218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
24318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressDPadCenter() {
24418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
24518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return pressKeyCode(KeyEvent.KEYCODE_DPAD_CENTER);
24618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
24718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
24818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
24918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the DOWN button.
25018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
25118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
25218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
25318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressDPadDown() {
25418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
25518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN);
25618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
25718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
25818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
25918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the UP button.
26018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
26118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
26218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
26318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressDPadUp() {
26418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
26518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return pressKeyCode(KeyEvent.KEYCODE_DPAD_UP);
26618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
26718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
26818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
26918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the LEFT button.
27018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
27118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
27218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
27318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressDPadLeft() {
27418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
27518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT);
27618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
27718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
27818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
27918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the RIGHT button.
28018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
28118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
28218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
28318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressDPadRight() {
28418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
28518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT);
28618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
28718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
28818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
28918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the DELETE key.
29018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
29118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
29218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
29318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressDelete() {
29418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
29518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return pressKeyCode(KeyEvent.KEYCODE_DEL);
29618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
29718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
29818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
29918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the ENTER key.
30018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
30118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
30218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
30318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressEnter() {
30418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
30518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return pressKeyCode(KeyEvent.KEYCODE_ENTER);
30618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
30718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
30818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
30918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press using a key code.
31018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
31118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * See {@link KeyEvent}
31218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
31318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
31418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
31518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressKeyCode(int keyCode) {
31618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(keyCode);
31718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
31818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().sendKey(keyCode, 0);
31918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
32018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
32118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
32218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press using a key code.
32318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
32418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * See {@link KeyEvent}.
32518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param keyCode the key code of the event.
32618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param metaState an integer in which each bit set to 1 represents a pressed meta key
32718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
32818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
32918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
33018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressKeyCode(int keyCode, int metaState) {
33118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(keyCode, metaState);
33218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
33318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().sendKey(keyCode, metaState);
33418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
33518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
33618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
33718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates a short press on the Recent Apps button.
33818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
33918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
34018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @throws RemoteException
34118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
34218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
34318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean pressRecentApps() throws RemoteException {
34418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
34518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
34618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().toggleRecentApps();
34718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
34818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
34918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
35018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Opens the notification shade.
35118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
35218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
35318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 18
35418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
35518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean openNotification() {
35618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
35718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
35818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return  getAutomatorBridge().getInteractionController().openNotification();
35918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
36018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
36118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
36218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Opens the Quick Settings shade.
36318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
36418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if successful, else return false
36518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 18
36618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
36718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean openQuickSettings() {
36818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
36918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
37018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().openQuickSettings();
37118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
37218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
37318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
37418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Gets the width of the display, in pixels. The width and height details
37518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * are reported based on the current orientation of the display.
37618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return width in pixels or zero on failure
37718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
37818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
37918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public int getDisplayWidth() {
38018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
38118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Display display = getAutomatorBridge().getDefaultDisplay();
38218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Point p = new Point();
38318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        display.getSize(p);
38418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return p.x;
38518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
38618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
38718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
38818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Gets the height of the display, in pixels. The size is adjusted based
38918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * on the current orientation of the display.
39018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return height in pixels or zero on failure
39118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
39218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
39318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public int getDisplayHeight() {
39418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
39518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Display display = getAutomatorBridge().getDefaultDisplay();
39618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Point p = new Point();
39718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        display.getSize(p);
39818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return p.y;
39918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
40018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
40118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
40218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Perform a click at arbitrary coordinates specified by the user
40318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
40418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param x coordinate
40518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param y coordinate
40618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if the click succeeded else false
40718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
40818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
40918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean click(int x, int y) {
41018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(x, y);
41118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (x >= getDisplayWidth() || y >= getDisplayHeight()) {
41218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            return (false);
41318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
41418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().clickNoSync(x, y);
41518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
41618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
41718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
41818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Performs a swipe from one coordinate to another using the number of steps
41918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * to determine smoothness and speed. Each step execution is throttled to 5ms
42018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * per step. So for a 100 steps, the swipe will take about 1/2 second to complete.
42118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
42218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param startX
42318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param startY
42418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param endX
42518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param endY
42618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param steps is the number of move steps sent to the system
42718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return false if the operation fails or the coordinates are invalid
42818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
42918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
43018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean swipe(int startX, int startY, int endX, int endY, int steps) {
43118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(startX, startY, endX, endY, steps);
43218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController()
43318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                .swipe(startX, startY, endX, endY, steps);
43418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
43518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
43618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
43718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Performs a swipe from one coordinate to another coordinate. You can control
43818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * the smoothness and speed of the swipe by specifying the number of steps.
43918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Each step execution is throttled to 5 milliseconds per step, so for a 100
44018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * steps, the swipe will take around 0.5 seconds to complete.
44118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
44218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param startX X-axis value for the starting coordinate
44318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param startY Y-axis value for the starting coordinate
44418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param endX X-axis value for the ending coordinate
44518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param endY Y-axis value for the ending coordinate
44618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param steps is the number of steps for the swipe action
44718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if swipe is performed, false if the operation fails
44818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * or the coordinates are invalid
44918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 18
45018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
45118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean drag(int startX, int startY, int endX, int endY, int steps) {
45218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(startX, startY, endX, endY, steps);
45318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController()
45418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                .swipe(startX, startY, endX, endY, steps, true);
45518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
45618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
45718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
45818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Performs a swipe between points in the Point array. Each step execution is throttled
45918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * to 5ms per step. So for a 100 steps, the swipe will take about 1/2 second to complete
46018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
46118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param segments is Point array containing at least one Point object
46218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param segmentSteps steps to inject between two Points
46318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true on success
46418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
46518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
46618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean swipe(Point[] segments, int segmentSteps) {
46718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(segments, segmentSteps);
46818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().swipe(segments, segmentSteps);
46918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
47018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
47118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
47218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Waits for the current application to idle.
47318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Default wait timeout is 10 seconds
47418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
47518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
47618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void waitForIdle() {
47718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
47818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle(Configurator.getInstance().getWaitForIdleTimeout());
47918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
48018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
48118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
48218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Waits for the current application to idle.
48318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param timeout in milliseconds
48418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
48518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
48618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void waitForIdle(long timeout) {
48718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(timeout);
48818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        getAutomatorBridge().waitForIdle(timeout);
48918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
49018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
49118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
49218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Retrieves the last activity to report accessibility events.
49318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @deprecated The results returned should be considered unreliable
49418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return String name of activity
49518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
49618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
49718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    @Deprecated
49818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public String getCurrentActivityName() {
49918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
50018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getQueryController().getCurrentActivityName();
50118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
50218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
50318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
50418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Retrieves the name of the last package to report accessibility events.
50518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return String name of package
50618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
50718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
50818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public String getCurrentPackageName() {
50918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
51018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getQueryController().getCurrentPackageName();
51118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
51218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
51318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
51418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Registers a {@link UiWatcher} to run automatically when the testing framework is unable to
51518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * find a match using a {@link UiSelector}. See {@link #runWatchers()}
51618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
51718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param name to register the UiWatcher
51818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param watcher {@link UiWatcher}
51918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
52018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
52118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void registerWatcher(String name, UiWatcher watcher) {
52218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(name, watcher);
52318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (mInWatcherContext) {
52418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            throw new IllegalStateException("Cannot register new watcher from within another");
52518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
52618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        mWatchers.put(name, watcher);
52718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
52818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
52918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
53018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Removes a previously registered {@link UiWatcher}.
53118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
53218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * See {@link #registerWatcher(String, UiWatcher)}
53318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param name used to register the UiWatcher
53418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
53518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
53618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void removeWatcher(String name) {
53718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(name);
53818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (mInWatcherContext) {
53918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            throw new IllegalStateException("Cannot remove a watcher from within another");
54018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
54118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        mWatchers.remove(name);
54218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
54318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
54418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
54518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * This method forces all registered watchers to run.
54618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * See {@link #registerWatcher(String, UiWatcher)}
54718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
54818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
54918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void runWatchers() {
55018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
55118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (mInWatcherContext) {
55218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            return;
55318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
55418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
55518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        for (String watcherName : mWatchers.keySet()) {
55618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            UiWatcher watcher = mWatchers.get(watcherName);
55718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            if (watcher != null) {
55818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                try {
55918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    mInWatcherContext = true;
56018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    if (watcher.checkForCondition()) {
56118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                        setWatcherTriggered(watcherName);
56218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    }
56318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                } catch (Exception e) {
56418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    Log.e(LOG_TAG, "Exceuting watcher: " + watcherName, e);
56518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                } finally {
56618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    mInWatcherContext = false;
56718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                }
56818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            }
56918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
57018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
57118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
57218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
57318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Resets a {@link UiWatcher} that has been triggered.
57418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * If a UiWatcher runs and its {@link UiWatcher#checkForCondition()} call
57518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * returned <code>true</code>, then the UiWatcher is considered triggered.
57618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * See {@link #registerWatcher(String, UiWatcher)}
57718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
57818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
57918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void resetWatcherTriggers() {
58018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
58118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        mWatchersTriggers.clear();
58218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
58318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
58418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
58518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Checks if a specific registered  {@link UiWatcher} has triggered.
58618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * See {@link #registerWatcher(String, UiWatcher)}. If a UiWatcher runs and its
58718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * {@link UiWatcher#checkForCondition()} call returned <code>true</code>, then
58818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * the UiWatcher is considered triggered. This is helpful if a watcher is detecting errors
58918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * from ANR or crash dialogs and the test needs to know if a UiWatcher has been triggered.
59018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
59118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param watcherName
59218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if triggered else false
59318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
59418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
59518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean hasWatcherTriggered(String watcherName) {
59618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(watcherName);
59718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mWatchersTriggers.contains(watcherName);
59818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
59918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
60018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
60118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Checks if any registered {@link UiWatcher} have triggered.
60218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
60318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * See {@link #registerWatcher(String, UiWatcher)}
60418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * See {@link #hasWatcherTriggered(String)}
60518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
60618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
60718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean hasAnyWatcherTriggered() {
60818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
60918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mWatchersTriggers.size() > 0;
61018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
61118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
61218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
61318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Used internally by this class to set a {@link UiWatcher} state as triggered.
61418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param watcherName
61518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
61618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private void setWatcherTriggered(String watcherName) {
61718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(watcherName);
61818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (!hasWatcherTriggered(watcherName)) {
61918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            mWatchersTriggers.add(watcherName);
62018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
62118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
62218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
62318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
62418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Check if the device is in its natural orientation. This is determined by checking if the
62518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * orientation is at 0 or 180 degrees.
62618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if it is in natural orientation
62718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 17
62818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
62918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean isNaturalOrientation() {
63018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
63118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
63218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        int ret = getAutomatorBridge().getRotation();
63318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return ret == UiAutomation.ROTATION_FREEZE_0 ||
63418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                ret == UiAutomation.ROTATION_FREEZE_180;
63518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
63618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
63718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
63818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Returns the current rotation of the display, as defined in {@link Surface}
63918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 17
64018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
64118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public int getDisplayRotation() {
64218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
64318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle();
64418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getRotation();
64518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
64618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
64718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
64818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Disables the sensors and freezes the device rotation at its
64918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * current rotation state.
65018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @throws RemoteException
65118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
65218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
65318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void freezeRotation() throws RemoteException {
65418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
65518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        getAutomatorBridge().getInteractionController().freezeRotation();
65618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
65718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
65818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
65918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Re-enables the sensors and un-freezes the device rotation allowing its contents
66018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * to rotate with the device physical rotation. During a test execution, it is best to
66118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * keep the device frozen in a specific orientation until the test case execution has completed.
66218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @throws RemoteException
66318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
66418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void unfreezeRotation() throws RemoteException {
66518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
66618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        getAutomatorBridge().getInteractionController().unfreezeRotation();
66718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
66818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
66918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
67018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates orienting the device to the left and also freezes rotation
67118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * by disabling the sensors.
67218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
67318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * If you want to un-freeze the rotation and re-enable the sensors
67418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * see {@link #unfreezeRotation()}.
67518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @throws RemoteException
67618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 17
67718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
67818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void setOrientationLeft() throws RemoteException {
67918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
68018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        getAutomatorBridge().getInteractionController().setRotationLeft();
68118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
68218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
68318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
68418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
68518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates orienting the device to the right and also freezes rotation
68618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * by disabling the sensors.
68718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
68818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * If you want to un-freeze the rotation and re-enable the sensors
68918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * see {@link #unfreezeRotation()}.
69018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @throws RemoteException
69118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 17
69218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
69318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void setOrientationRight() throws RemoteException {
69418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
69518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        getAutomatorBridge().getInteractionController().setRotationRight();
69618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
69718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
69818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
69918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
70018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Simulates orienting the device into its natural orientation and also freezes rotation
70118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * by disabling the sensors.
70218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
70318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * If you want to un-freeze the rotation and re-enable the sensors
70418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * see {@link #unfreezeRotation()}.
70518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @throws RemoteException
70618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 17
70718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
70818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void setOrientationNatural() throws RemoteException {
70918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
71018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        getAutomatorBridge().getInteractionController().setRotationNatural();
71118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
71218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
71318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
71418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
71518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * This method simulates pressing the power button if the screen is OFF else
71618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * it does nothing if the screen is already ON.
71718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
71818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * If the screen was OFF and it just got turned ON, this method will insert a 500ms delay
71918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * to allow the device time to wake up and accept input.
72018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @throws RemoteException
72118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
72218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
72318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void wakeUp() throws RemoteException {
72418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
72518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if(getAutomatorBridge().getInteractionController().wakeDevice()) {
72618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            // sync delay to allow the window manager to start accepting input
72718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            // after the device is awakened.
72818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            SystemClock.sleep(500);
72918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
73018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
73118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
73218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
73318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Checks the power manager if the screen is ON.
73418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
73518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if the screen is ON else false
73618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @throws RemoteException
73718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
73818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
73918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean isScreenOn() throws RemoteException {
74018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
74118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().getInteractionController().isScreenOn();
74218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
74318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
74418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
74518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * This method simply presses the power button if the screen is ON else
74618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * it does nothing if the screen is already OFF.
74718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
74818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @throws RemoteException
74918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
75018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
75118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void sleep() throws RemoteException {
75218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace();
75318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        getAutomatorBridge().getInteractionController().sleepDevice();
75418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
75518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
75618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
75718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Helper method used for debugging to dump the current window's layout hierarchy.
75818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * The file root location is /data/local/tmp
75918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
76018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param fileName
76118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
76218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
76318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void dumpWindowHierarchy(String fileName) {
76418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(fileName);
76518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        AccessibilityNodeInfo root =
76618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                getAutomatorBridge().getQueryController().getAccessibilityRootNode();
76718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if(root != null) {
76818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            Display display = getAutomatorBridge().getDefaultDisplay();
76918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            Point size = new Point();
77018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            display.getSize(size);
77118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            AccessibilityNodeInfoDumper.dumpWindowToFile(root,
77218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    new File(new File(Environment.getDataDirectory(), "local/tmp"), fileName),
77318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    display.getRotation(), size.x, size.y);
77418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
77518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
77618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
77718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
77818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Waits for a window content update event to occur.
77918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
78018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * If a package name for the window is specified, but the current window
78118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * does not have the same package name, the function returns immediately.
78218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
78318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param packageName the specified window package name (can be <code>null</code>).
78418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *        If <code>null</code>, a window update from any front-end window will end the wait
78518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param timeout the timeout for the wait
78618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
78718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if a window update occurred, false if timeout has elapsed or if the current
78818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *         window does not have the specified package name
78918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 16
79018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
79118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean waitForWindowUpdate(final String packageName, long timeout) {
79218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(packageName, timeout);
79318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (packageName != null) {
79418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            if (!packageName.equals(getCurrentPackageName())) {
79518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                return false;
79618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            }
79718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
79818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Runnable emptyRunnable = new Runnable() {
79918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            @Override
80018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            public void run() {
80118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            }
80218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        };
80318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        AccessibilityEventFilter checkWindowUpdate = new AccessibilityEventFilter() {
80418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            @Override
80518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            public boolean accept(AccessibilityEvent t) {
80618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                if (t.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
80718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    return packageName == null || packageName.equals(t.getPackageName());
80818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                }
80918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                return false;
81018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            }
81118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        };
81218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        try {
81318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            getAutomatorBridge().executeCommandAndWaitForAccessibilityEvent(
81418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    emptyRunnable, checkWindowUpdate, timeout);
81518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        } catch (TimeoutException e) {
81618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            return false;
81718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        } catch (Exception e) {
81818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            Log.e(LOG_TAG, "waitForWindowUpdate: general exception from bridge", e);
81918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            return false;
82018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
82118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return true;
82218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
82318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
82418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
82518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Take a screenshot of current window and store it as PNG
82618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
82718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Default scale of 1.0f (original size) and 90% quality is used
82818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * The screenshot is adjusted per screen rotation
82918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
83018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param storePath where the PNG should be written to
83118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if screen shot is created successfully, false otherwise
83218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 17
83318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
83418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean takeScreenshot(File storePath) {
83518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(storePath);
83618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return takeScreenshot(storePath, 1.0f, 90);
83718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
83818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
83918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    /**
84018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * Take a screenshot of current window and store it as PNG
84118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
84218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * The screenshot is adjusted per screen rotation
84318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     *
84418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param storePath where the PNG should be written to
84518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param scale scale the screenshot down if needed; 1.0f for original size
84618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @param quality quality of the PNG compression; range: 0-100
84718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @return true if screen shot is created successfully, false otherwise
84818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     * @since API Level 17
84918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu     */
85018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean takeScreenshot(File storePath, float scale, int quality) {
85118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Tracer.trace(storePath, scale, quality);
85218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return getAutomatorBridge().takeScreenshot(storePath, quality);
85318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
85418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu}
855