180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov/*
280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * Copyright (C) 2013 The Android Open Source Project
380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov *
480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * you may not use this file except in compliance with the License.
680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * You may obtain a copy of the License at
780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov *
880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov *
1080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * Unless required by applicable law or agreed to in writing, software
1180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
1280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * See the License for the specific language governing permissions and
1480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * limitations under the License.
1580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov */
1680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
1780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovpackage android.app;
1880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
1980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.accessibilityservice.AccessibilityServiceInfo;
2080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.accessibilityservice.IAccessibilityServiceClient;
2180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.content.Context;
2252153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganovimport android.content.pm.IPackageManager;
2380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.graphics.Bitmap;
2480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.hardware.input.InputManager;
2580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.os.Binder;
261376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslavimport android.os.IBinder;
27121e0c073992658ca0ba055f40bf3b130caa819aSvetoslavimport android.os.ParcelFileDescriptor;
2880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.os.Process;
2980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.os.RemoteException;
3080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.os.ServiceManager;
31e2239c9346b9efb8c879c1925d90f70c4eb2405cFyodor Kupolovimport android.os.UserHandle;
3280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.view.IWindowManager;
3380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.view.InputEvent;
343866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.view.SurfaceControl;
351376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslavimport android.view.WindowAnimationFrameStats;
361376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslavimport android.view.WindowContentFrameStats;
3780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
3880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.view.accessibility.IAccessibilityManager;
39b5e89c6debca90be92bf5bc2e0e79d109de6d08fJeff Sharkey
40121e0c073992658ca0ba055f40bf3b130caa819aSvetoslavimport libcore.io.IoUtils;
41121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav
42121e0c073992658ca0ba055f40bf3b130caa819aSvetoslavimport java.io.FileOutputStream;
43121e0c073992658ca0ba055f40bf3b130caa819aSvetoslavimport java.io.IOException;
44121e0c073992658ca0ba055f40bf3b130caa819aSvetoslavimport java.io.InputStream;
45121e0c073992658ca0ba055f40bf3b130caa819aSvetoslavimport java.io.OutputStream;
4680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
4780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov/**
4880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * This is a remote object that is passed from the shell to an instrumentation
4980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * for enabling access to privileged operations which the shell can do and the
5080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * instrumentation cannot. These privileged operations are needed for implementing
5180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * a {@link UiAutomation} that enables across application testing by simulating
5280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * user actions and performing screen introspection.
5380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov *
5480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * @hide
5580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov */
5680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovpublic final class UiAutomationConnection extends IUiAutomationConnection.Stub {
5780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
5880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private static final int INITIAL_FROZEN_ROTATION_UNSPECIFIED = -1;
5980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
6080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private final IWindowManager mWindowManager = IWindowManager.Stub.asInterface(
6180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            ServiceManager.getService(Service.WINDOW_SERVICE));
6280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
63121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav    private final IAccessibilityManager mAccessibilityManager = IAccessibilityManager.Stub
64121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav            .asInterface(ServiceManager.getService(Service.ACCESSIBILITY_SERVICE));
651376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav
6652153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov    private final IPackageManager mPackageManager = IPackageManager.Stub
6752153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            .asInterface(ServiceManager.getService("package"));
6852153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov
6980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private final Object mLock = new Object();
7080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
713c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav    private final Binder mToken = new Binder();
723c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav
7380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private int mInitialFrozenRotation = INITIAL_FROZEN_ROTATION_UNSPECIFIED;
7480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
7580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private IAccessibilityServiceClient mClient;
7680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
7780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private boolean mIsShutdown;
7880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
7980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private int mOwningUid;
8080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
81b5e89c6debca90be92bf5bc2e0e79d109de6d08fJeff Sharkey    @Override
821dd872260b3ccfbe492d1be0bdbb3f98235b3ba3Phil Weaver    public void connect(IAccessibilityServiceClient client, int flags) {
8380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        if (client == null) {
8480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalArgumentException("Client cannot be null!");
8580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
8680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
8780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
8880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (isConnectedLocked()) {
8980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                throw new IllegalStateException("Already connected.");
9080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
9180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mOwningUid = Binder.getCallingUid();
921dd872260b3ccfbe492d1be0bdbb3f98235b3ba3Phil Weaver            registerUiTestAutomationServiceLocked(client, flags);
9380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            storeRotationStateLocked();
9480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
9580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
9680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
9780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
9880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public void disconnect() {
9980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
10080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfCalledByNotTrustedUidLocked();
10180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
10280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (!isConnectedLocked()) {
10380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                throw new IllegalStateException("Already disconnected.");
10480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
10580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mOwningUid = -1;
10680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            unregisterUiTestAutomationServiceLocked();
10780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            restoreRotationStateLocked();
10880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
10980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
11080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
11180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
11280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public boolean injectInputEvent(InputEvent event, boolean sync) {
11380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
11480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfCalledByNotTrustedUidLocked();
11580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
11680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfNotConnectedLocked();
11780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
11880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final int mode = (sync) ? InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
11980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                : InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
12080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final long identity = Binder.clearCallingIdentity();
12180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
12280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            return InputManager.getInstance().injectInputEvent(event, mode);
12380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } finally {
12480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            Binder.restoreCallingIdentity(identity);
12580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
12680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
12780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
12880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
12980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public boolean setRotation(int rotation) {
13080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
13180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfCalledByNotTrustedUidLocked();
13280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
13380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfNotConnectedLocked();
13480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
13580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final long identity = Binder.clearCallingIdentity();
13680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
13780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (rotation == UiAutomation.ROTATION_UNFREEZE) {
13880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mWindowManager.thawRotation();
13980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            } else {
14080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mWindowManager.freezeRotation(rotation);
14180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
14280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            return true;
14380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
14480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            /* ignore */
14580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } finally {
14680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            Binder.restoreCallingIdentity(identity);
14780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
14880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        return false;
14980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
15080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
15180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
15280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public Bitmap takeScreenshot(int width, int height) {
15380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
15480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfCalledByNotTrustedUidLocked();
15580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
15680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfNotConnectedLocked();
15780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
15880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final long identity = Binder.clearCallingIdentity();
15980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
1603866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            return SurfaceControl.screenshot(width, height);
16180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } finally {
16280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            Binder.restoreCallingIdentity(identity);
16380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
16480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
16580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
16680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
1671376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    public boolean clearWindowContentFrameStats(int windowId) throws RemoteException {
1681376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        synchronized (mLock) {
1691376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfCalledByNotTrustedUidLocked();
1701376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfShutdownLocked();
1711376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfNotConnectedLocked();
1721376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        }
173e2239c9346b9efb8c879c1925d90f70c4eb2405cFyodor Kupolov        int callingUserId = UserHandle.getCallingUserId();
1741376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        final long identity = Binder.clearCallingIdentity();
1751376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        try {
176e2239c9346b9efb8c879c1925d90f70c4eb2405cFyodor Kupolov            IBinder token = mAccessibilityManager.getWindowToken(windowId, callingUserId);
1771376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            if (token == null) {
1781376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav                return false;
1791376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            }
1801376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            return mWindowManager.clearWindowContentFrameStats(token);
1811376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        } finally {
1821376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            Binder.restoreCallingIdentity(identity);
1831376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        }
1841376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    }
1851376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav
1861376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
1871376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    public WindowContentFrameStats getWindowContentFrameStats(int windowId) throws RemoteException {
1881376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        synchronized (mLock) {
1891376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfCalledByNotTrustedUidLocked();
1901376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfShutdownLocked();
1911376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfNotConnectedLocked();
1921376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        }
193e2239c9346b9efb8c879c1925d90f70c4eb2405cFyodor Kupolov        int callingUserId = UserHandle.getCallingUserId();
1941376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        final long identity = Binder.clearCallingIdentity();
1951376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        try {
196e2239c9346b9efb8c879c1925d90f70c4eb2405cFyodor Kupolov            IBinder token = mAccessibilityManager.getWindowToken(windowId, callingUserId);
1971376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            if (token == null) {
1981376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav                return null;
1991376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            }
2001376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            return mWindowManager.getWindowContentFrameStats(token);
2011376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        } finally {
2021376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            Binder.restoreCallingIdentity(identity);
2031376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        }
2041376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    }
2051376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav
2061376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
2071376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    public void clearWindowAnimationFrameStats() {
2081376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        synchronized (mLock) {
2091376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfCalledByNotTrustedUidLocked();
2101376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfShutdownLocked();
2111376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfNotConnectedLocked();
2121376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        }
2131376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        final long identity = Binder.clearCallingIdentity();
2141376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        try {
2151376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            SurfaceControl.clearAnimationFrameStats();
2161376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        } finally {
2171376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            Binder.restoreCallingIdentity(identity);
2181376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        }
2191376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    }
2201376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav
2211376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
2221376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    public WindowAnimationFrameStats getWindowAnimationFrameStats() {
2231376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        synchronized (mLock) {
2241376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfCalledByNotTrustedUidLocked();
2251376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfShutdownLocked();
2261376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            throwIfNotConnectedLocked();
2271376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        }
2281376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        final long identity = Binder.clearCallingIdentity();
2291376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        try {
2301376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            WindowAnimationFrameStats stats = new WindowAnimationFrameStats();
2311376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            SurfaceControl.getAnimationFrameStats(stats);
2321376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            return stats;
2331376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        } finally {
2341376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            Binder.restoreCallingIdentity(identity);
2351376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        }
2361376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    }
2371376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav
2381376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
23952153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov    public void grantRuntimePermission(String packageName, String permission, int userId)
24052153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            throws RemoteException {
24152153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        synchronized (mLock) {
24252153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            throwIfCalledByNotTrustedUidLocked();
24352153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            throwIfShutdownLocked();
24452153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            throwIfNotConnectedLocked();
24552153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        }
24652153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        final long identity = Binder.clearCallingIdentity();
24752153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        try {
24852153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            mPackageManager.grantRuntimePermission(packageName, permission, userId);
24952153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        } finally {
25052153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            Binder.restoreCallingIdentity(identity);
25152153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        }
25252153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov    }
25352153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov
25452153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov    @Override
25552153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov    public void revokeRuntimePermission(String packageName, String permission, int userId)
25652153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            throws RemoteException {
25752153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        synchronized (mLock) {
25852153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            throwIfCalledByNotTrustedUidLocked();
25952153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            throwIfShutdownLocked();
26052153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            throwIfNotConnectedLocked();
26152153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        }
26252153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        final long identity = Binder.clearCallingIdentity();
26352153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        try {
26452153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            mPackageManager.revokeRuntimePermission(packageName, permission, userId);
26552153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        } finally {
26652153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov            Binder.restoreCallingIdentity(identity);
26752153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        }
26852153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov    }
26952153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov
27052153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov    @Override
27114e260125e951c2c6372dae80b603996cbb4d362Guang Zhu    public void executeShellCommand(final String command, final ParcelFileDescriptor sink)
272121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav            throws RemoteException {
273121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav        synchronized (mLock) {
274121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav            throwIfCalledByNotTrustedUidLocked();
275121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav            throwIfShutdownLocked();
276121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav            throwIfNotConnectedLocked();
277121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav        }
278121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav
27914e260125e951c2c6372dae80b603996cbb4d362Guang Zhu        Thread streamReader = new Thread() {
28014e260125e951c2c6372dae80b603996cbb4d362Guang Zhu            public void run() {
28114e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                InputStream in = null;
28214e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                OutputStream out = null;
283843b992b51d18c893f3665325ea3045a692832acGuang Zhu                java.lang.Process process = null;
284121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav
28514e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                try {
286843b992b51d18c893f3665325ea3045a692832acGuang Zhu                    process = Runtime.getRuntime().exec(command);
287121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav
28814e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                    in = process.getInputStream();
28914e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                    out = new FileOutputStream(sink.getFileDescriptor());
290121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav
29114e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                    final byte[] buffer = new byte[8192];
29214e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                    while (true) {
29314e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                        final int readByteCount = in.read(buffer);
29414e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                        if (readByteCount < 0) {
29514e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                            break;
29614e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                        }
29714e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                        out.write(buffer, 0, readByteCount);
29814e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                    }
29914e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                } catch (IOException ioe) {
30014e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                    throw new RuntimeException("Error running shell command", ioe);
30114e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                } finally {
302843b992b51d18c893f3665325ea3045a692832acGuang Zhu                    if (process != null) {
303843b992b51d18c893f3665325ea3045a692832acGuang Zhu                        process.destroy();
304843b992b51d18c893f3665325ea3045a692832acGuang Zhu                    }
30514e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                    IoUtils.closeQuietly(out);
30614e260125e951c2c6372dae80b603996cbb4d362Guang Zhu                    IoUtils.closeQuietly(sink);
307121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav                }
30814e260125e951c2c6372dae80b603996cbb4d362Guang Zhu            };
30914e260125e951c2c6372dae80b603996cbb4d362Guang Zhu        };
31014e260125e951c2c6372dae80b603996cbb4d362Guang Zhu        streamReader.start();
311121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav    }
312121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav
313121e0c073992658ca0ba055f40bf3b130caa819aSvetoslav    @Override
31480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public void shutdown() {
31580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
3169663fd09e9dc14a17d3828665ab11a256c4a5c96Svetoslav            if (isConnectedLocked()) {
3179663fd09e9dc14a17d3828665ab11a256c4a5c96Svetoslav                throwIfCalledByNotTrustedUidLocked();
3189663fd09e9dc14a17d3828665ab11a256c4a5c96Svetoslav            }
31980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
32080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mIsShutdown = true;
32180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (isConnectedLocked()) {
32280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                disconnect();
32380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
32480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
32580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
32680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
3271dd872260b3ccfbe492d1be0bdbb3f98235b3ba3Phil Weaver    private void registerUiTestAutomationServiceLocked(IAccessibilityServiceClient client,
3281dd872260b3ccfbe492d1be0bdbb3f98235b3ba3Phil Weaver            int flags) {
32980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
33080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
331b5e89c6debca90be92bf5bc2e0e79d109de6d08fJeff Sharkey        final AccessibilityServiceInfo info = new AccessibilityServiceInfo();
33280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
33380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
33480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
335b5e89c6debca90be92bf5bc2e0e79d109de6d08fJeff Sharkey                | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS
336b5e89c6debca90be92bf5bc2e0e79d109de6d08fJeff Sharkey                | AccessibilityServiceInfo.FLAG_FORCE_DIRECT_BOOT_AWARE;
33711adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav        info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
33811adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
33911adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
34011adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS);
34180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
34280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            // Calling out with a lock held is fine since if the system
34380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            // process is gone the client calling in will be killed.
3441dd872260b3ccfbe492d1be0bdbb3f98235b3ba3Phil Weaver            manager.registerUiTestAutomationService(mToken, client, info, flags);
34580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mClient = client;
34680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
34780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalStateException("Error while registering UiTestAutomationService.", re);
34880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
34980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
35080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
35180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void unregisterUiTestAutomationServiceLocked() {
35280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
35380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov              ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
35480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
35580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            // Calling out with a lock held is fine since if the system
35680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            // process is gone the client calling in will be killed.
35780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            manager.unregisterUiTestAutomationService(mClient);
35880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mClient = null;
35980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
36080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalStateException("Error while unregistering UiTestAutomationService",
36180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                    re);
36280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
36380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
36480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
36580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void storeRotationStateLocked() {
36680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
36780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (mWindowManager.isRotationFrozen()) {
36880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // Calling out with a lock held is fine since if the system
36980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // process is gone the client calling in will be killed.
37080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mInitialFrozenRotation = mWindowManager.getRotation();
37180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
37280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
37380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            /* ignore */
37480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
37580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
37680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
37780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void restoreRotationStateLocked() {
37880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
37980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (mInitialFrozenRotation != INITIAL_FROZEN_ROTATION_UNSPECIFIED) {
38080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // Calling out with a lock held is fine since if the system
38180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // process is gone the client calling in will be killed.
38280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mWindowManager.freezeRotation(mInitialFrozenRotation);
38380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            } else {
38480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // Calling out with a lock held is fine since if the system
38580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // process is gone the client calling in will be killed.
38680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mWindowManager.thawRotation();
38780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
38880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
38980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            /* ignore */
39080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
39180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
39280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
39380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private boolean isConnectedLocked() {
39480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        return mClient != null;
39580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
39680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
39780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void throwIfShutdownLocked() {
39880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        if (mIsShutdown) {
39980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalStateException("Connection shutdown!");
40080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
40180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
40280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
40380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void throwIfNotConnectedLocked() {
40480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        if (!isConnectedLocked()) {
40580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalStateException("Not connected!");
40680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
40780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
40880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
40980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void throwIfCalledByNotTrustedUidLocked() {
41080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final int callingUid = Binder.getCallingUid();
41180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        if (callingUid != mOwningUid && mOwningUid != Process.SYSTEM_UID
41280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                && callingUid != 0 /*root*/) {
41380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new SecurityException("Calling from not trusted UID!");
41480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
41580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
41680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov}
417