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