DreamManagerService.java revision 2687550272ba061448f5d5b914700dc335299ee7
1f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock/*
2f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Copyright (C) 2012 The Android Open Source Project
3f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock *
4f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License");
5f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * you may not use this file except in compliance with the License.
6f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * You may obtain a copy of the License at
7f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock *
8f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock *      http://www.apache.org/licenses/LICENSE-2.0
9f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock *
10f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Unless required by applicable law or agreed to in writing, software
11f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS,
12f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * See the License for the specific language governing permissions and
14f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * limitations under the License.
15f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock */
16f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
17cef440f2a2bb8b6e8d082d12a67dc21f2ee65e3cJeff Brownpackage com.android.server.dreams;
18f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
1962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport com.android.internal.util.DumpUtils;
204ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brownimport com.android.server.FgThread;
21567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownimport com.android.server.SystemService;
22f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
23567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownimport android.Manifest;
2462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport android.app.ActivityManager;
25f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.BroadcastReceiver;
26f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.ComponentName;
27f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.Context;
28f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.Intent;
29f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.IntentFilter;
30f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.pm.PackageManager;
31bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlockimport android.content.pm.PackageManager.NameNotFoundException;
32f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.Binder;
332687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.os.Build;
34f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.Handler;
35f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.IBinder;
3662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport android.os.Looper;
3762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport android.os.PowerManager;
3862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport android.os.SystemClock;
392687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.os.SystemProperties;
40f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.UserHandle;
41f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.provider.Settings;
42567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownimport android.service.dreams.DreamManagerInternal;
43567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownimport android.service.dreams.DreamService;
442687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.service.dreams.IDozeHardware;
45f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.service.dreams.IDreamManager;
462687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.text.TextUtils;
47f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.util.Slog;
48f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
49f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.io.FileDescriptor;
50f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.io.PrintWriter;
51bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlockimport java.util.ArrayList;
52bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlockimport java.util.List;
53f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
5462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport libcore.util.Objects;
5562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
56f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock/**
57f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Service api for managing dreams.
58f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock *
59f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * @hide
60f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock */
61567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownpublic final class DreamManagerService extends SystemService {
6240e9f2922cae76ffcbc521481e5be8e80e8744efDianne Hackborn    private static final boolean DEBUG = false;
6362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private static final String TAG = "DreamManagerService";
64f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
65f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    private final Object mLock = new Object();
66f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
6762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final Context mContext;
6862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final DreamHandler mHandler;
6962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final DreamController mController;
7062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final PowerManager mPowerManager;
712687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private final PowerManager.WakeLock mDozeWakeLock;
722687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private final McuHal mMcuHal; // synchronized on self
73f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
7462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private Binder mCurrentDreamToken;
7562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private ComponentName mCurrentDreamName;
7662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private int mCurrentDreamUserId;
7762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private boolean mCurrentDreamIsTest;
782687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private boolean mCurrentDreamCanDoze;
792687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private boolean mCurrentDreamIsDozing;
802687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private DozeHardwareWrapper mCurrentDreamDozeHardware;
81f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
824ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown    public DreamManagerService(Context context) {
83567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        super(context);
84f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        mContext = context;
854ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown        mHandler = new DreamHandler(FgThread.get().getLooper());
8662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mController = new DreamController(context, mHandler, mControllerListener);
8762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
8862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
892687550272ba061448f5d5b914700dc335299ee7Jeff Brown        mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, TAG);
902687550272ba061448f5d5b914700dc335299ee7Jeff Brown
912687550272ba061448f5d5b914700dc335299ee7Jeff Brown        mMcuHal = McuHal.open();
922687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (mMcuHal != null) {
932687550272ba061448f5d5b914700dc335299ee7Jeff Brown            mMcuHal.reset();
942687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
95f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
96f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
97567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    @Override
98567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    public void onStart() {
99567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        publishBinderService(DreamService.DREAM_SERVICE, new BinderService());
100567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        publishLocalService(DreamManagerInternal.class, new LocalService());
101f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
102f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
103f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    @Override
104567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    public void onBootPhase(int phase) {
105567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
106567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            mContext.registerReceiver(new BroadcastReceiver() {
107567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                @Override
108567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                public void onReceive(Context context, Intent intent) {
109567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                    synchronized (mLock) {
110567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                        stopDreamLocked();
111567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                    }
112567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                }
113567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
114da5b6f2dc4ba23b6b70209f9b34fb39c93a51fc4John Spurlock        }
115567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
116f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
117567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void dumpInternal(PrintWriter pw) {
11862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("DREAM MANAGER (dumpsys dreams)");
11962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println();
12062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
1212687550272ba061448f5d5b914700dc335299ee7Jeff Brown        pw.println("mMcuHal=" + mMcuHal);
1222687550272ba061448f5d5b914700dc335299ee7Jeff Brown        pw.println();
12362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("mCurrentDreamToken=" + mCurrentDreamToken);
12462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("mCurrentDreamName=" + mCurrentDreamName);
12562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("mCurrentDreamUserId=" + mCurrentDreamUserId);
12662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest);
1272687550272ba061448f5d5b914700dc335299ee7Jeff Brown        pw.println("mCurrentDreamCanDoze=" + mCurrentDreamCanDoze);
1282687550272ba061448f5d5b914700dc335299ee7Jeff Brown        pw.println("mCurrentDreamIsDozing=" + mCurrentDreamIsDozing);
1292687550272ba061448f5d5b914700dc335299ee7Jeff Brown        pw.println("mCurrentDreamDozeHardware=" + mCurrentDreamDozeHardware);
13062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println();
13162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
13262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() {
13362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            @Override
13462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            public void dump(PrintWriter pw) {
13562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                mController.dump(pw);
13662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
13762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }, pw, 200);
138f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
139f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
140567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private boolean isDreamingInternal() {
14162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        synchronized (mLock) {
14262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            return mCurrentDreamToken != null && !mCurrentDreamIsTest;
14362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
144f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
145f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
146567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void requestDreamInternal() {
147567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // Ask the power manager to nap.  It will eventually call back into
148567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // startDream() if/when it is appropriate to start dreaming.
149567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // Because napping could cause the screen to turn off immediately if the dream
150567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // cannot be started, we keep one eye open and gently poke user activity.
151567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        long time = SystemClock.uptimeMillis();
152567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        mPowerManager.userActivity(time, true /*noChangeLights*/);
153567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        mPowerManager.nap(time);
154f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
155f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
156567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void requestAwakenInternal() {
157567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // Treat an explicit request to awaken as user activity so that the
158567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // device doesn't immediately go to sleep if the timeout expired,
159567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // for example when being undocked.
160567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        long time = SystemClock.uptimeMillis();
161567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        mPowerManager.userActivity(time, false /*noChangeLights*/);
162567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        stopDreamInternal();
163567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
164f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
165567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void finishSelfInternal(IBinder token) {
166567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        if (DEBUG) {
167567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            Slog.d(TAG, "Dream finished: " + token);
16862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
16962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
170567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // Note that a dream finishing and self-terminating is not
171567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // itself considered user activity.  If the dream is ending because
172567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // the user interacted with the device then user activity will already
173567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // have been poked so the device will stay awake a bit longer.
174567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // If the dream is ending on its own for other reasons and no wake
175567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // locks are held and the user activity timeout has expired then the
176567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // device may simply go to sleep.
177567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        synchronized (mLock) {
178567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (mCurrentDreamToken == token) {
179567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                stopDreamLocked();
180f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            }
181f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
182f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
183f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
184567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void testDreamInternal(ComponentName dream, int userId) {
185567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        synchronized (mLock) {
1862687550272ba061448f5d5b914700dc335299ee7Jeff Brown            startDreamLocked(dream, true /*isTest*/, false /*canDoze*/, userId);
187f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
188f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
189f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
1902687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private void startDreamInternal(boolean doze) {
1912687550272ba061448f5d5b914700dc335299ee7Jeff Brown        final int userId = ActivityManager.getCurrentUser();
1922687550272ba061448f5d5b914700dc335299ee7Jeff Brown        final ComponentName dream = doze ? getDozeComponent() : chooseDreamForUser(userId);
19362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (dream != null) {
19462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            synchronized (mLock) {
1952687550272ba061448f5d5b914700dc335299ee7Jeff Brown                startDreamLocked(dream, false /*isTest*/, doze, userId);
19662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
19762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
198f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
199f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
200567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void stopDreamInternal() {
20162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        synchronized (mLock) {
20262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            stopDreamLocked();
203f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
204f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
205f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
2062687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private void startDozingInternal(IBinder token) {
2072687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (DEBUG) {
2082687550272ba061448f5d5b914700dc335299ee7Jeff Brown            Slog.d(TAG, "Dream requested to start dozing: " + token);
2092687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
2102687550272ba061448f5d5b914700dc335299ee7Jeff Brown
2112687550272ba061448f5d5b914700dc335299ee7Jeff Brown        synchronized (mLock) {
2122687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (mCurrentDreamToken == token && mCurrentDreamCanDoze
2132687550272ba061448f5d5b914700dc335299ee7Jeff Brown                    && !mCurrentDreamIsDozing) {
2142687550272ba061448f5d5b914700dc335299ee7Jeff Brown                mCurrentDreamIsDozing = true;
2152687550272ba061448f5d5b914700dc335299ee7Jeff Brown                mDozeWakeLock.acquire();
2162687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
2172687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
2182687550272ba061448f5d5b914700dc335299ee7Jeff Brown    }
2192687550272ba061448f5d5b914700dc335299ee7Jeff Brown
2202687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private void stopDozingInternal(IBinder token) {
2212687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (DEBUG) {
2222687550272ba061448f5d5b914700dc335299ee7Jeff Brown            Slog.d(TAG, "Dream requested to stop dozing: " + token);
2232687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
2242687550272ba061448f5d5b914700dc335299ee7Jeff Brown
2252687550272ba061448f5d5b914700dc335299ee7Jeff Brown        synchronized (mLock) {
2262687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (mCurrentDreamToken == token && mCurrentDreamIsDozing) {
2272687550272ba061448f5d5b914700dc335299ee7Jeff Brown                mCurrentDreamIsDozing = false;
2282687550272ba061448f5d5b914700dc335299ee7Jeff Brown                mDozeWakeLock.release();
2292687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
2302687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
2312687550272ba061448f5d5b914700dc335299ee7Jeff Brown    }
2322687550272ba061448f5d5b914700dc335299ee7Jeff Brown
2332687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private IDozeHardware getDozeHardwareInternal(IBinder token) {
2342687550272ba061448f5d5b914700dc335299ee7Jeff Brown        synchronized (mLock) {
2352687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (mCurrentDreamToken == token && mCurrentDreamCanDoze
2362687550272ba061448f5d5b914700dc335299ee7Jeff Brown                    && mCurrentDreamDozeHardware == null && mMcuHal != null) {
2372687550272ba061448f5d5b914700dc335299ee7Jeff Brown                mCurrentDreamDozeHardware = new DozeHardwareWrapper();
2382687550272ba061448f5d5b914700dc335299ee7Jeff Brown                return mCurrentDreamDozeHardware;
2392687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
2402687550272ba061448f5d5b914700dc335299ee7Jeff Brown            return null;
2412687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
2422687550272ba061448f5d5b914700dc335299ee7Jeff Brown    }
2432687550272ba061448f5d5b914700dc335299ee7Jeff Brown
24462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private ComponentName chooseDreamForUser(int userId) {
24562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        ComponentName[] dreams = getDreamComponentsForUser(userId);
24662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        return dreams != null && dreams.length != 0 ? dreams[0] : null;
247f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
248f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
249f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    private ComponentName[] getDreamComponentsForUser(int userId) {
250f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
25162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                Settings.Secure.SCREENSAVER_COMPONENTS,
252f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                userId);
253bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        ComponentName[] components = componentsFromString(names);
254bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock
255bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        // first, ensure components point to valid services
256bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        List<ComponentName> validComponents = new ArrayList<ComponentName>();
257bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        if (components != null) {
258bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            for (ComponentName component : components) {
259bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                if (serviceExists(component)) {
260bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                    validComponents.add(component);
261bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                } else {
262bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                    Slog.w(TAG, "Dream " + component + " does not exist");
263bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                }
264bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            }
265bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        }
266bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock
267bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        // fallback to the default dream component if necessary
268bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        if (validComponents.isEmpty()) {
269567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            ComponentName defaultDream = getDefaultDreamComponentForUser(userId);
270bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            if (defaultDream != null) {
271bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                Slog.w(TAG, "Falling back to default dream " + defaultDream);
272bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                validComponents.add(defaultDream);
273bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            }
274bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        }
275bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        return validComponents.toArray(new ComponentName[validComponents.size()]);
276bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock    }
277bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock
278567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void setDreamComponentsForUser(int userId, ComponentName[] componentNames) {
279567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        Settings.Secure.putStringForUser(mContext.getContentResolver(),
280567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Settings.Secure.SCREENSAVER_COMPONENTS,
281567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                componentsToString(componentNames),
282567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                userId);
283567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
284567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
285567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private ComponentName getDefaultDreamComponentForUser(int userId) {
286567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
287567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
288567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                userId);
289567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        return name == null ? null : ComponentName.unflattenFromString(name);
290567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
291567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
2922687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private ComponentName getDozeComponent() {
2932687550272ba061448f5d5b914700dc335299ee7Jeff Brown        // Read the component from a system property to facilitate debugging.
2942687550272ba061448f5d5b914700dc335299ee7Jeff Brown        // Note that for production devices, the dream should actually be declared in
2952687550272ba061448f5d5b914700dc335299ee7Jeff Brown        // a config.xml resource.
2962687550272ba061448f5d5b914700dc335299ee7Jeff Brown        String name = Build.IS_DEBUGGABLE ? SystemProperties.get("debug.doze.component") : null;
2972687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (TextUtils.isEmpty(name)) {
2982687550272ba061448f5d5b914700dc335299ee7Jeff Brown            // Read the component from a config.xml resource.
2992687550272ba061448f5d5b914700dc335299ee7Jeff Brown            // The value should be specified in a resource overlay for the product.
3002687550272ba061448f5d5b914700dc335299ee7Jeff Brown            name = mContext.getResources().getString(
3012687550272ba061448f5d5b914700dc335299ee7Jeff Brown                    com.android.internal.R.string.config_dozeComponent);
3022687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
3032687550272ba061448f5d5b914700dc335299ee7Jeff Brown        return TextUtils.isEmpty(name) ? null : ComponentName.unflattenFromString(name);
3042687550272ba061448f5d5b914700dc335299ee7Jeff Brown    }
3052687550272ba061448f5d5b914700dc335299ee7Jeff Brown
306bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock    private boolean serviceExists(ComponentName name) {
307bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        try {
308bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null;
309bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        } catch (NameNotFoundException e) {
310bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            return false;
311bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        }
312f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
313f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
31462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private void startDreamLocked(final ComponentName name,
3152687550272ba061448f5d5b914700dc335299ee7Jeff Brown            final boolean isTest, final boolean canDoze, final int userId) {
31662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (Objects.equal(mCurrentDreamName, name)
31762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                && mCurrentDreamIsTest == isTest
3182687550272ba061448f5d5b914700dc335299ee7Jeff Brown                && mCurrentDreamCanDoze == canDoze
31962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                && mCurrentDreamUserId == userId) {
32062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            return;
32162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
32262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
32362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        stopDreamLocked();
32462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
32540e9f2922cae76ffcbc521481e5be8e80e8744efDianne Hackborn        if (DEBUG) Slog.i(TAG, "Entering dreamland.");
32662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
32762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        final Binder newToken = new Binder();
32862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamToken = newToken;
32962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamName = name;
33062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamIsTest = isTest;
3312687550272ba061448f5d5b914700dc335299ee7Jeff Brown        mCurrentDreamCanDoze = canDoze;
33262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamUserId = userId;
33362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
33462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mHandler.post(new Runnable() {
33562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            @Override
33662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            public void run() {
3372687550272ba061448f5d5b914700dc335299ee7Jeff Brown                mController.startDream(newToken, name, isTest, canDoze, userId);
33862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
33962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        });
34062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
34162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
34262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private void stopDreamLocked() {
34362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (mCurrentDreamToken != null) {
34440e9f2922cae76ffcbc521481e5be8e80e8744efDianne Hackborn            if (DEBUG) Slog.i(TAG, "Leaving dreamland.");
34562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
34662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            cleanupDreamLocked();
34762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
34862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            mHandler.post(new Runnable() {
34962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                @Override
35062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                public void run() {
35162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                    mController.stopDream();
35262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                }
35362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            });
35462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
35562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
35662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
35762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private void cleanupDreamLocked() {
35862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamToken = null;
35962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamName = null;
36062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamIsTest = false;
3612687550272ba061448f5d5b914700dc335299ee7Jeff Brown        mCurrentDreamCanDoze = false;
36262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamUserId = 0;
3632687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (mCurrentDreamIsDozing) {
3642687550272ba061448f5d5b914700dc335299ee7Jeff Brown            mCurrentDreamIsDozing = false;
3652687550272ba061448f5d5b914700dc335299ee7Jeff Brown            mDozeWakeLock.release();
3662687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
3672687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (mCurrentDreamDozeHardware != null) {
3682687550272ba061448f5d5b914700dc335299ee7Jeff Brown            mCurrentDreamDozeHardware.release();
3692687550272ba061448f5d5b914700dc335299ee7Jeff Brown            mCurrentDreamDozeHardware = null;
3702687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
37162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
37262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
37362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private void checkPermission(String permission) {
37462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (mContext.checkCallingOrSelfPermission(permission)
37562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                != PackageManager.PERMISSION_GRANTED) {
37662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
37762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                    + ", must have permission " + permission);
37862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
37962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
38062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
381f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    private static String componentsToString(ComponentName[] componentNames) {
382f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        StringBuilder names = new StringBuilder();
383f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        if (componentNames != null) {
384f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            for (ComponentName componentName : componentNames) {
385f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                if (names.length() > 0) {
386f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                    names.append(',');
387f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                }
388f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                names.append(componentName.flattenToString());
389f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            }
390f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
391f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        return names.toString();
392f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
393f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
394f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    private static ComponentName[] componentsFromString(String names) {
395f5df689aa65682ce9217405e4a6b686e94129e8fJohn Spurlock        if (names == null) {
396f5df689aa65682ce9217405e4a6b686e94129e8fJohn Spurlock            return null;
397f5df689aa65682ce9217405e4a6b686e94129e8fJohn Spurlock        }
398f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        String[] namesArray = names.split(",");
399f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        ComponentName[] componentNames = new ComponentName[namesArray.length];
400f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        for (int i = 0; i < namesArray.length; i++) {
401f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            componentNames[i] = ComponentName.unflattenFromString(namesArray[i]);
402f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
403f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        return componentNames;
404f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
405f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
40662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final DreamController.Listener mControllerListener = new DreamController.Listener() {
40762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        @Override
40862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        public void onDreamStopped(Binder token) {
40962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            synchronized (mLock) {
41062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                if (mCurrentDreamToken == token) {
41162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                    cleanupDreamLocked();
412f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                }
413f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            }
414f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
41562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    };
416f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
417f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    /**
418f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock     * Handler for asynchronous operations performed by the dream manager.
419f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock     * Ensures operations to {@link DreamController} are single-threaded.
420f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock     */
42162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final class DreamHandler extends Handler {
42262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        public DreamHandler(Looper looper) {
42362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            super(looper, null, true /*async*/);
424f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
425f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
426567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
427567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private final class BinderService extends IDreamManager.Stub {
428567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
429567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
430567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
431567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                    != PackageManager.PERMISSION_GRANTED) {
432567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                pw.println("Permission Denial: can't dump DreamManager from from pid="
433567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                        + Binder.getCallingPid()
434567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                        + ", uid=" + Binder.getCallingUid());
435567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return;
436567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
437567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
438567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
439567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
440567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                dumpInternal(pw);
441567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
442567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
443567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
444567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
445567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
446567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
447567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public ComponentName[] getDreamComponents() {
448567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.READ_DREAM_STATE);
449567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
450567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int userId = UserHandle.getCallingUserId();
451567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
452567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
453567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return getDreamComponentsForUser(userId);
454567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
455567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
456567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
457567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
458567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
459567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
460567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void setDreamComponents(ComponentName[] componentNames) {
461567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
462567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
463567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int userId = UserHandle.getCallingUserId();
464567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
465567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
466567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                setDreamComponentsForUser(userId, componentNames);
467567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
468567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
469567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
470567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
471567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
472567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
473567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public ComponentName getDefaultDreamComponent() {
474567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.READ_DREAM_STATE);
475567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
476567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int userId = UserHandle.getCallingUserId();
477567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
478567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
479567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return getDefaultDreamComponentForUser(userId);
480567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
481567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
482567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
483567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
484567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
485567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
486567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public boolean isDreaming() {
487567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.READ_DREAM_STATE);
488567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
489567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
490567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
491567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return isDreamingInternal();
492567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
493567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
494567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
495567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
496567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
497567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
498567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void dream() {
499567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
500567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
501567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
502567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
503567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                requestDreamInternal();
504567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
505567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
506567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
507567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
508567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
509567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
510567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void testDream(ComponentName dream) {
511567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (dream == null) {
512567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                throw new IllegalArgumentException("dream must not be null");
513567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
514567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
515567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
516567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int callingUserId = UserHandle.getCallingUserId();
517567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int currentUserId = ActivityManager.getCurrentUser();
518567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (callingUserId != currentUserId) {
519567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                // This check is inherently prone to races but at least it's something.
520567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Slog.w(TAG, "Aborted attempt to start a test dream while a different "
521567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                        + " user is active: callingUserId=" + callingUserId
522567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                        + ", currentUserId=" + currentUserId);
523567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return;
524567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
525567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
526567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
527567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                testDreamInternal(dream, callingUserId);
528567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
529567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
530567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
531567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
532567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
533567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
534567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void awaken() {
535567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
536567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
537567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
538567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
539567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                requestAwakenInternal();
540567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
541567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
542567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
543567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
544567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
545567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
546567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void finishSelf(IBinder token) {
547567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            // Requires no permission, called by Dream from an arbitrary process.
548567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (token == null) {
549567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                throw new IllegalArgumentException("token must not be null");
550567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
551567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
552567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
553567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
554567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                finishSelfInternal(token);
555567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
556567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
557567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
558567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
5592687550272ba061448f5d5b914700dc335299ee7Jeff Brown
5602687550272ba061448f5d5b914700dc335299ee7Jeff Brown        @Override // Binder call
5612687550272ba061448f5d5b914700dc335299ee7Jeff Brown        public void startDozing(IBinder token) {
5622687550272ba061448f5d5b914700dc335299ee7Jeff Brown            // Requires no permission, called by Dream from an arbitrary process.
5632687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (token == null) {
5642687550272ba061448f5d5b914700dc335299ee7Jeff Brown                throw new IllegalArgumentException("token must not be null");
5652687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
5662687550272ba061448f5d5b914700dc335299ee7Jeff Brown
5672687550272ba061448f5d5b914700dc335299ee7Jeff Brown            final long ident = Binder.clearCallingIdentity();
5682687550272ba061448f5d5b914700dc335299ee7Jeff Brown            try {
5692687550272ba061448f5d5b914700dc335299ee7Jeff Brown                startDozingInternal(token);
5702687550272ba061448f5d5b914700dc335299ee7Jeff Brown            } finally {
5712687550272ba061448f5d5b914700dc335299ee7Jeff Brown                Binder.restoreCallingIdentity(ident);
5722687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
5732687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
5742687550272ba061448f5d5b914700dc335299ee7Jeff Brown
5752687550272ba061448f5d5b914700dc335299ee7Jeff Brown        @Override // Binder call
5762687550272ba061448f5d5b914700dc335299ee7Jeff Brown        public void stopDozing(IBinder token) {
5772687550272ba061448f5d5b914700dc335299ee7Jeff Brown            // Requires no permission, called by Dream from an arbitrary process.
5782687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (token == null) {
5792687550272ba061448f5d5b914700dc335299ee7Jeff Brown                throw new IllegalArgumentException("token must not be null");
5802687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
5812687550272ba061448f5d5b914700dc335299ee7Jeff Brown
5822687550272ba061448f5d5b914700dc335299ee7Jeff Brown            final long ident = Binder.clearCallingIdentity();
5832687550272ba061448f5d5b914700dc335299ee7Jeff Brown            try {
5842687550272ba061448f5d5b914700dc335299ee7Jeff Brown                stopDozingInternal(token);
5852687550272ba061448f5d5b914700dc335299ee7Jeff Brown            } finally {
5862687550272ba061448f5d5b914700dc335299ee7Jeff Brown                Binder.restoreCallingIdentity(ident);
5872687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
5882687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
5892687550272ba061448f5d5b914700dc335299ee7Jeff Brown
5902687550272ba061448f5d5b914700dc335299ee7Jeff Brown        @Override // Binder call
5912687550272ba061448f5d5b914700dc335299ee7Jeff Brown        public IDozeHardware getDozeHardware(IBinder token) {
5922687550272ba061448f5d5b914700dc335299ee7Jeff Brown            // Requires no permission, called by Dream from an arbitrary process.
5932687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (token == null) {
5942687550272ba061448f5d5b914700dc335299ee7Jeff Brown                throw new IllegalArgumentException("token must not be null");
5952687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
5962687550272ba061448f5d5b914700dc335299ee7Jeff Brown
5972687550272ba061448f5d5b914700dc335299ee7Jeff Brown            final long ident = Binder.clearCallingIdentity();
5982687550272ba061448f5d5b914700dc335299ee7Jeff Brown            try {
5992687550272ba061448f5d5b914700dc335299ee7Jeff Brown                return getDozeHardwareInternal(token);
6002687550272ba061448f5d5b914700dc335299ee7Jeff Brown            } finally {
6012687550272ba061448f5d5b914700dc335299ee7Jeff Brown                Binder.restoreCallingIdentity(ident);
6022687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
6032687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
604567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
605567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
606567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private final class LocalService extends DreamManagerInternal {
607567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override
6082687550272ba061448f5d5b914700dc335299ee7Jeff Brown        public void startDream(boolean doze) {
6092687550272ba061448f5d5b914700dc335299ee7Jeff Brown            startDreamInternal(doze);
610567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
611567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
612567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override
613567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void stopDream() {
614567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            stopDreamInternal();
615567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
616567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
617567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override
618567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public boolean isDreaming() {
619567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            return isDreamingInternal();
620567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
621567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
6222687550272ba061448f5d5b914700dc335299ee7Jeff Brown
6232687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private final class DozeHardwareWrapper extends IDozeHardware.Stub {
6242687550272ba061448f5d5b914700dc335299ee7Jeff Brown        private boolean mReleased;
6252687550272ba061448f5d5b914700dc335299ee7Jeff Brown
6262687550272ba061448f5d5b914700dc335299ee7Jeff Brown        public void release() {
6272687550272ba061448f5d5b914700dc335299ee7Jeff Brown            synchronized (mMcuHal) {
6282687550272ba061448f5d5b914700dc335299ee7Jeff Brown                if (!mReleased) {
6292687550272ba061448f5d5b914700dc335299ee7Jeff Brown                    mReleased = true;
6302687550272ba061448f5d5b914700dc335299ee7Jeff Brown                    mMcuHal.reset();
6312687550272ba061448f5d5b914700dc335299ee7Jeff Brown                }
6322687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
6332687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
6342687550272ba061448f5d5b914700dc335299ee7Jeff Brown
6352687550272ba061448f5d5b914700dc335299ee7Jeff Brown        @Override // Binder call
6362687550272ba061448f5d5b914700dc335299ee7Jeff Brown        public byte[] sendMessage(String msg, byte[] arg) {
6372687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (msg == null) {
6382687550272ba061448f5d5b914700dc335299ee7Jeff Brown                throw new IllegalArgumentException("msg must not be null");
6392687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
6402687550272ba061448f5d5b914700dc335299ee7Jeff Brown
6412687550272ba061448f5d5b914700dc335299ee7Jeff Brown            final long ident = Binder.clearCallingIdentity();
6422687550272ba061448f5d5b914700dc335299ee7Jeff Brown            try {
6432687550272ba061448f5d5b914700dc335299ee7Jeff Brown                synchronized (mMcuHal) {
6442687550272ba061448f5d5b914700dc335299ee7Jeff Brown                    if (mReleased) {
6452687550272ba061448f5d5b914700dc335299ee7Jeff Brown                        throw new IllegalStateException("This operation cannot be performed "
6462687550272ba061448f5d5b914700dc335299ee7Jeff Brown                                + "because the dream has ended.");
6472687550272ba061448f5d5b914700dc335299ee7Jeff Brown                    }
6482687550272ba061448f5d5b914700dc335299ee7Jeff Brown                    return mMcuHal.sendMessage(msg, arg);
6492687550272ba061448f5d5b914700dc335299ee7Jeff Brown                }
6502687550272ba061448f5d5b914700dc335299ee7Jeff Brown            } finally {
6512687550272ba061448f5d5b914700dc335299ee7Jeff Brown                Binder.restoreCallingIdentity(ident);
6522687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
6532687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
6542687550272ba061448f5d5b914700dc335299ee7Jeff Brown    }
655f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock}
656