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;
2280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.graphics.Bitmap;
2380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.hardware.input.InputManager;
2480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.os.Binder;
2580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.os.Process;
2680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.os.RemoteException;
2780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.os.ServiceManager;
2880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.view.IWindowManager;
2980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.view.InputEvent;
303866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.view.SurfaceControl;
3180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
3280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovimport android.view.accessibility.IAccessibilityManager;
3380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
3480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov/**
3580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * This is a remote object that is passed from the shell to an instrumentation
3680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * for enabling access to privileged operations which the shell can do and the
3780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * instrumentation cannot. These privileged operations are needed for implementing
3880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * a {@link UiAutomation} that enables across application testing by simulating
3980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * user actions and performing screen introspection.
4080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov *
4180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov * @hide
4280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov */
4380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganovpublic final class UiAutomationConnection extends IUiAutomationConnection.Stub {
4480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
4580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private static final int INITIAL_FROZEN_ROTATION_UNSPECIFIED = -1;
4680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
4780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private final IWindowManager mWindowManager = IWindowManager.Stub.asInterface(
4880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            ServiceManager.getService(Service.WINDOW_SERVICE));
4980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
5080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private final Object mLock = new Object();
5180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
523c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav    private final Binder mToken = new Binder();
533c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav
5480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private int mInitialFrozenRotation = INITIAL_FROZEN_ROTATION_UNSPECIFIED;
5580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
5680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private IAccessibilityServiceClient mClient;
5780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
5880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private boolean mIsShutdown;
5980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
6080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private int mOwningUid;
6180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
6280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public void connect(IAccessibilityServiceClient client) {
6380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        if (client == null) {
6480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalArgumentException("Client cannot be null!");
6580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
6680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
6780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
6880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (isConnectedLocked()) {
6980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                throw new IllegalStateException("Already connected.");
7080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
7180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mOwningUid = Binder.getCallingUid();
7280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            registerUiTestAutomationServiceLocked(client);
7380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            storeRotationStateLocked();
7480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
7580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
7680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
7780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
7880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public void disconnect() {
7980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
8080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfCalledByNotTrustedUidLocked();
8180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
8280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (!isConnectedLocked()) {
8380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                throw new IllegalStateException("Already disconnected.");
8480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
8580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mOwningUid = -1;
8680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            unregisterUiTestAutomationServiceLocked();
8780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            restoreRotationStateLocked();
8880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
8980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
9080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
9180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
9280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public boolean injectInputEvent(InputEvent event, boolean sync) {
9380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
9480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfCalledByNotTrustedUidLocked();
9580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
9680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfNotConnectedLocked();
9780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
9880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final int mode = (sync) ? InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
9980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                : InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
10080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final long identity = Binder.clearCallingIdentity();
10180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
10280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            return InputManager.getInstance().injectInputEvent(event, mode);
10380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } finally {
10480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            Binder.restoreCallingIdentity(identity);
10580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
10680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
10780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
10880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
10980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public boolean setRotation(int rotation) {
11080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
11180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfCalledByNotTrustedUidLocked();
11280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
11380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfNotConnectedLocked();
11480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
11580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final long identity = Binder.clearCallingIdentity();
11680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
11780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (rotation == UiAutomation.ROTATION_UNFREEZE) {
11880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mWindowManager.thawRotation();
11980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            } else {
12080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mWindowManager.freezeRotation(rotation);
12180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
12280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            return true;
12380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
12480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            /* ignore */
12580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } finally {
12680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            Binder.restoreCallingIdentity(identity);
12780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
12880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        return false;
12980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
13080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
13180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
13280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public Bitmap takeScreenshot(int width, int height) {
13380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
13480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfCalledByNotTrustedUidLocked();
13580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
13680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfNotConnectedLocked();
13780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
13880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final long identity = Binder.clearCallingIdentity();
13980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
1403866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            return SurfaceControl.screenshot(width, height);
14180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } finally {
14280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            Binder.restoreCallingIdentity(identity);
14380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
14480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
14580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
14680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    @Override
14780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public void shutdown() {
14880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        synchronized (mLock) {
14980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfCalledByNotTrustedUidLocked();
15080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throwIfShutdownLocked();
15180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mIsShutdown = true;
15280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (isConnectedLocked()) {
15380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                disconnect();
15480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
15580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
15680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
15780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
15880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void registerUiTestAutomationServiceLocked(IAccessibilityServiceClient client) {
15980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
16080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
16111adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
16280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
16380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
16480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
16580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS;
16611adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav        info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
16711adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
16811adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
16911adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS);
17080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
17180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            // Calling out with a lock held is fine since if the system
17280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            // process is gone the client calling in will be killed.
1733c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            manager.registerUiTestAutomationService(mToken, client, info);
17480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mClient = client;
17580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
17680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalStateException("Error while registering UiTestAutomationService.", re);
17780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
17880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
17980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
18080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void unregisterUiTestAutomationServiceLocked() {
18180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
18280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov              ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
18380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
18480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            // Calling out with a lock held is fine since if the system
18580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            // process is gone the client calling in will be killed.
18680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            manager.unregisterUiTestAutomationService(mClient);
18780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            mClient = null;
18880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
18980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalStateException("Error while unregistering UiTestAutomationService",
19080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                    re);
19180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
19280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
19380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
19480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void storeRotationStateLocked() {
19580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
19680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (mWindowManager.isRotationFrozen()) {
19780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // Calling out with a lock held is fine since if the system
19880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // process is gone the client calling in will be killed.
19980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mInitialFrozenRotation = mWindowManager.getRotation();
20080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
20180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
20280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            /* ignore */
20380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
20480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
20580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
20680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void restoreRotationStateLocked() {
20780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        try {
20880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            if (mInitialFrozenRotation != INITIAL_FROZEN_ROTATION_UNSPECIFIED) {
20980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // Calling out with a lock held is fine since if the system
21080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // process is gone the client calling in will be killed.
21180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mWindowManager.freezeRotation(mInitialFrozenRotation);
21280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            } else {
21380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // Calling out with a lock held is fine since if the system
21480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                // process is gone the client calling in will be killed.
21580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                mWindowManager.thawRotation();
21680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
21780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        } catch (RemoteException re) {
21880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            /* ignore */
21980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
22080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
22180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
22280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private boolean isConnectedLocked() {
22380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        return mClient != null;
22480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
22580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
22680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void throwIfShutdownLocked() {
22780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        if (mIsShutdown) {
22880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalStateException("Connection shutdown!");
22980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
23080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
23180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
23280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void throwIfNotConnectedLocked() {
23380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        if (!isConnectedLocked()) {
23480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new IllegalStateException("Not connected!");
23580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
23680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
23780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
23880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    private void throwIfCalledByNotTrustedUidLocked() {
23980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        final int callingUid = Binder.getCallingUid();
24080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        if (callingUid != mOwningUid && mOwningUid != Process.SYSTEM_UID
24180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                && callingUid != 0 /*root*/) {
24280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            throw new SecurityException("Calling from not trusted UID!");
24380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        }
24480943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    }
24580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov}
246