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
19eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlockimport static android.Manifest.permission.BIND_DREAM_SERVICE;
20eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock
2162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport com.android.internal.util.DumpUtils;
224ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brownimport com.android.server.FgThread;
23567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownimport com.android.server.SystemService;
24f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
25567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownimport android.Manifest;
2662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport android.app.ActivityManager;
27f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.BroadcastReceiver;
28f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.ComponentName;
29f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.Context;
30f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.Intent;
31f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.IntentFilter;
32f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.pm.PackageManager;
33bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlockimport android.content.pm.PackageManager.NameNotFoundException;
34eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlockimport android.content.pm.ServiceInfo;
35f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.Binder;
362687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.os.Build;
37f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.Handler;
38f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.IBinder;
3962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport android.os.Looper;
4062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport android.os.PowerManager;
41970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brownimport android.os.PowerManagerInternal;
4262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport android.os.SystemClock;
432687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.os.SystemProperties;
44f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.UserHandle;
45f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.provider.Settings;
46567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownimport android.service.dreams.DreamManagerInternal;
47567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownimport android.service.dreams.DreamService;
48f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.service.dreams.IDreamManager;
492687550272ba061448f5d5b914700dc335299ee7Jeff Brownimport android.text.TextUtils;
50f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.util.Slog;
51970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brownimport android.view.Display;
52f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
53f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.io.FileDescriptor;
54f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.io.PrintWriter;
55bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlockimport java.util.ArrayList;
56bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlockimport java.util.List;
57f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
5862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport libcore.util.Objects;
5962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
60f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock/**
61f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Service api for managing dreams.
62f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock *
63f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * @hide
64f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock */
65567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brownpublic final class DreamManagerService extends SystemService {
6640e9f2922cae76ffcbc521481e5be8e80e8744efDianne Hackborn    private static final boolean DEBUG = false;
6762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private static final String TAG = "DreamManagerService";
68f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
69f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    private final Object mLock = new Object();
70f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
7162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final Context mContext;
7262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final DreamHandler mHandler;
7362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final DreamController mController;
7462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final PowerManager mPowerManager;
75970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown    private final PowerManagerInternal mPowerManagerInternal;
762687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private final PowerManager.WakeLock mDozeWakeLock;
77f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
7862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private Binder mCurrentDreamToken;
7962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private ComponentName mCurrentDreamName;
8062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private int mCurrentDreamUserId;
8162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private boolean mCurrentDreamIsTest;
822687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private boolean mCurrentDreamCanDoze;
832687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private boolean mCurrentDreamIsDozing;
84f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown    private boolean mCurrentDreamIsWaking;
85970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown    private int mCurrentDreamDozeScreenState = Display.STATE_UNKNOWN;
86970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown    private int mCurrentDreamDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
87f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
884ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown    public DreamManagerService(Context context) {
89567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        super(context);
90f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        mContext = context;
914ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown        mHandler = new DreamHandler(FgThread.get().getLooper());
9262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mController = new DreamController(context, mHandler, mControllerListener);
9362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
9462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
95970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown        mPowerManagerInternal = getLocalService(PowerManagerInternal.class);
962687550272ba061448f5d5b914700dc335299ee7Jeff Brown        mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, TAG);
97f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
98f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
99567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    @Override
100567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    public void onStart() {
101567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        publishBinderService(DreamService.DREAM_SERVICE, new BinderService());
102567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        publishLocalService(DreamManagerInternal.class, new LocalService());
103f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
104f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
105f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    @Override
106567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    public void onBootPhase(int phase) {
107567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
108bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock            if (Build.IS_DEBUGGABLE) {
109bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock                SystemProperties.addChangeCallback(mSystemPropertiesChanged);
110bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock            }
111567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            mContext.registerReceiver(new BroadcastReceiver() {
112567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                @Override
113567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                public void onReceive(Context context, Intent intent) {
114567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                    synchronized (mLock) {
115f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                        stopDreamLocked(false /*immediate*/);
116567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                    }
117567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                }
118567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
119da5b6f2dc4ba23b6b70209f9b34fb39c93a51fc4John Spurlock        }
120567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
121f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
122567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void dumpInternal(PrintWriter pw) {
12362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("DREAM MANAGER (dumpsys dreams)");
12462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println();
12562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("mCurrentDreamToken=" + mCurrentDreamToken);
12662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("mCurrentDreamName=" + mCurrentDreamName);
12762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("mCurrentDreamUserId=" + mCurrentDreamUserId);
12862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest);
1292687550272ba061448f5d5b914700dc335299ee7Jeff Brown        pw.println("mCurrentDreamCanDoze=" + mCurrentDreamCanDoze);
1302687550272ba061448f5d5b914700dc335299ee7Jeff Brown        pw.println("mCurrentDreamIsDozing=" + mCurrentDreamIsDozing);
131f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown        pw.println("mCurrentDreamIsWaking=" + mCurrentDreamIsWaking);
132970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown        pw.println("mCurrentDreamDozeScreenState="
133970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                + Display.stateToString(mCurrentDreamDozeScreenState));
134970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown        pw.println("mCurrentDreamDozeScreenBrightness=" + mCurrentDreamDozeScreenBrightness);
135bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock        pw.println("getDozeComponent()=" + getDozeComponent());
13662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        pw.println();
13762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
13862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() {
13962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            @Override
14062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            public void dump(PrintWriter pw) {
14162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                mController.dump(pw);
14262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
14362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }, pw, 200);
144f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
145f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
146567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private boolean isDreamingInternal() {
14762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        synchronized (mLock) {
148f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown            return mCurrentDreamToken != null && !mCurrentDreamIsTest
149f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                    && !mCurrentDreamIsWaking;
15062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
151f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
152f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
153567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void requestDreamInternal() {
154567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // Ask the power manager to nap.  It will eventually call back into
155567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // startDream() if/when it is appropriate to start dreaming.
156567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // Because napping could cause the screen to turn off immediately if the dream
157567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // cannot be started, we keep one eye open and gently poke user activity.
158567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        long time = SystemClock.uptimeMillis();
159567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        mPowerManager.userActivity(time, true /*noChangeLights*/);
160567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        mPowerManager.nap(time);
161f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
162f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
163567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void requestAwakenInternal() {
164567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // Treat an explicit request to awaken as user activity so that the
165567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // device doesn't immediately go to sleep if the timeout expired,
166567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // for example when being undocked.
167567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        long time = SystemClock.uptimeMillis();
168567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        mPowerManager.userActivity(time, false /*noChangeLights*/);
169f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown        stopDreamInternal(false /*immediate*/);
170567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
171f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
172f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown    private void finishSelfInternal(IBinder token, boolean immediate) {
173567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        if (DEBUG) {
174f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown            Slog.d(TAG, "Dream finished: " + token + ", immediate=" + immediate);
17562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
17662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
177567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // Note that a dream finishing and self-terminating is not
178567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // itself considered user activity.  If the dream is ending because
179567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // the user interacted with the device then user activity will already
180567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // have been poked so the device will stay awake a bit longer.
181567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // If the dream is ending on its own for other reasons and no wake
182567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // locks are held and the user activity timeout has expired then the
183567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        // device may simply go to sleep.
184567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        synchronized (mLock) {
185567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (mCurrentDreamToken == token) {
186f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                stopDreamLocked(immediate);
187f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            }
188f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
189f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
190f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
191567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void testDreamInternal(ComponentName dream, int userId) {
192567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        synchronized (mLock) {
1932687550272ba061448f5d5b914700dc335299ee7Jeff Brown            startDreamLocked(dream, true /*isTest*/, false /*canDoze*/, userId);
194f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
195f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
196f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
1972687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private void startDreamInternal(boolean doze) {
1982687550272ba061448f5d5b914700dc335299ee7Jeff Brown        final int userId = ActivityManager.getCurrentUser();
199eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock        final ComponentName dream = chooseDreamForUser(doze, userId);
20062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (dream != null) {
20162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            synchronized (mLock) {
2022687550272ba061448f5d5b914700dc335299ee7Jeff Brown                startDreamLocked(dream, false /*isTest*/, doze, userId);
20362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
20462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
205f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
206f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
207f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown    private void stopDreamInternal(boolean immediate) {
20862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        synchronized (mLock) {
209f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown            stopDreamLocked(immediate);
210f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
211f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
212f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
213970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown    private void startDozingInternal(IBinder token, int screenState,
214970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown            int screenBrightness) {
2152687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (DEBUG) {
216970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown            Slog.d(TAG, "Dream requested to start dozing: " + token
217970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                    + ", screenState=" + screenState
218970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                    + ", screenBrightness=" + screenBrightness);
2192687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
2202687550272ba061448f5d5b914700dc335299ee7Jeff Brown
2212687550272ba061448f5d5b914700dc335299ee7Jeff Brown        synchronized (mLock) {
222970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown            if (mCurrentDreamToken == token && mCurrentDreamCanDoze) {
223970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                mCurrentDreamDozeScreenState = screenState;
224970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                mCurrentDreamDozeScreenBrightness = screenBrightness;
225970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                mPowerManagerInternal.setDozeOverrideFromDreamManager(
226970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                        screenState, screenBrightness);
227970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                if (!mCurrentDreamIsDozing) {
228970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                    mCurrentDreamIsDozing = true;
229970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                    mDozeWakeLock.acquire();
230970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                }
2312687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
2322687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
2332687550272ba061448f5d5b914700dc335299ee7Jeff Brown    }
2342687550272ba061448f5d5b914700dc335299ee7Jeff Brown
2352687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private void stopDozingInternal(IBinder token) {
2362687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (DEBUG) {
2372687550272ba061448f5d5b914700dc335299ee7Jeff Brown            Slog.d(TAG, "Dream requested to stop dozing: " + token);
2382687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
2392687550272ba061448f5d5b914700dc335299ee7Jeff Brown
2402687550272ba061448f5d5b914700dc335299ee7Jeff Brown        synchronized (mLock) {
2412687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (mCurrentDreamToken == token && mCurrentDreamIsDozing) {
2422687550272ba061448f5d5b914700dc335299ee7Jeff Brown                mCurrentDreamIsDozing = false;
2432687550272ba061448f5d5b914700dc335299ee7Jeff Brown                mDozeWakeLock.release();
244970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                mPowerManagerInternal.setDozeOverrideFromDreamManager(
245970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                        Display.STATE_UNKNOWN, PowerManager.BRIGHTNESS_DEFAULT);
2462687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
2472687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
2482687550272ba061448f5d5b914700dc335299ee7Jeff Brown    }
2492687550272ba061448f5d5b914700dc335299ee7Jeff Brown
250eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock    private ComponentName chooseDreamForUser(boolean doze, int userId) {
251eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock        if (doze) {
252a4215ceb86fbae3bcb40c4bd3b924e2b71cf50b6John Spurlock            ComponentName dozeComponent = getDozeComponent(userId);
253eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock            return validateDream(dozeComponent) ? dozeComponent : null;
254eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock        }
25562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        ComponentName[] dreams = getDreamComponentsForUser(userId);
25662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        return dreams != null && dreams.length != 0 ? dreams[0] : null;
257f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
258f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
259eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock    private boolean validateDream(ComponentName component) {
260eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock        if (component == null) return false;
261eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock        final ServiceInfo serviceInfo = getServiceInfo(component);
262eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock        if (serviceInfo == null) {
263eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock            Slog.w(TAG, "Dream " + component + " does not exist");
264eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock            return false;
265955d8d69ea6caabce1461dc25b339b9bf9dc61a6Dianne Hackborn        } else if (serviceInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP
266eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock                && !BIND_DREAM_SERVICE.equals(serviceInfo.permission)) {
267eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock            Slog.w(TAG, "Dream " + component
268eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock                    + " is not available because its manifest is missing the " + BIND_DREAM_SERVICE
269eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock                    + " permission on the dream service declaration.");
270eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock            return false;
271eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock        }
272eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock        return true;
273eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock    }
274eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock
275f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    private ComponentName[] getDreamComponentsForUser(int userId) {
276f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
27762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                Settings.Secure.SCREENSAVER_COMPONENTS,
278f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                userId);
279bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        ComponentName[] components = componentsFromString(names);
280bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock
281bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        // first, ensure components point to valid services
282bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        List<ComponentName> validComponents = new ArrayList<ComponentName>();
283bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        if (components != null) {
284bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            for (ComponentName component : components) {
285eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock                if (validateDream(component)) {
286bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                    validComponents.add(component);
287bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                }
288bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            }
289bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        }
290bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock
291bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        // fallback to the default dream component if necessary
292bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        if (validComponents.isEmpty()) {
293567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            ComponentName defaultDream = getDefaultDreamComponentForUser(userId);
294bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            if (defaultDream != null) {
295bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                Slog.w(TAG, "Falling back to default dream " + defaultDream);
296bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock                validComponents.add(defaultDream);
297bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock            }
298bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        }
299bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        return validComponents.toArray(new ComponentName[validComponents.size()]);
300bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock    }
301bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock
302567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private void setDreamComponentsForUser(int userId, ComponentName[] componentNames) {
303567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        Settings.Secure.putStringForUser(mContext.getContentResolver(),
304567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Settings.Secure.SCREENSAVER_COMPONENTS,
305567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                componentsToString(componentNames),
306567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                userId);
307567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
308567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
309567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private ComponentName getDefaultDreamComponentForUser(int userId) {
310567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
311567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
312567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                userId);
313567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        return name == null ? null : ComponentName.unflattenFromString(name);
314567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
315567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
3162687550272ba061448f5d5b914700dc335299ee7Jeff Brown    private ComponentName getDozeComponent() {
317a4215ceb86fbae3bcb40c4bd3b924e2b71cf50b6John Spurlock        return getDozeComponent(ActivityManager.getCurrentUser());
318a4215ceb86fbae3bcb40c4bd3b924e2b71cf50b6John Spurlock    }
319a4215ceb86fbae3bcb40c4bd3b924e2b71cf50b6John Spurlock
320a4215ceb86fbae3bcb40c4bd3b924e2b71cf50b6John Spurlock    private ComponentName getDozeComponent(int userId) {
3212687550272ba061448f5d5b914700dc335299ee7Jeff Brown        // Read the component from a system property to facilitate debugging.
3222687550272ba061448f5d5b914700dc335299ee7Jeff Brown        // Note that for production devices, the dream should actually be declared in
3232687550272ba061448f5d5b914700dc335299ee7Jeff Brown        // a config.xml resource.
3242687550272ba061448f5d5b914700dc335299ee7Jeff Brown        String name = Build.IS_DEBUGGABLE ? SystemProperties.get("debug.doze.component") : null;
3252687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (TextUtils.isEmpty(name)) {
3262687550272ba061448f5d5b914700dc335299ee7Jeff Brown            // Read the component from a config.xml resource.
3272687550272ba061448f5d5b914700dc335299ee7Jeff Brown            // The value should be specified in a resource overlay for the product.
3282687550272ba061448f5d5b914700dc335299ee7Jeff Brown            name = mContext.getResources().getString(
3292687550272ba061448f5d5b914700dc335299ee7Jeff Brown                    com.android.internal.R.string.config_dozeComponent);
3302687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
331a4215ceb86fbae3bcb40c4bd3b924e2b71cf50b6John Spurlock        boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
332a4215ceb86fbae3bcb40c4bd3b924e2b71cf50b6John Spurlock                Settings.Secure.DOZE_ENABLED, 1, userId) != 0;
333a4215ceb86fbae3bcb40c4bd3b924e2b71cf50b6John Spurlock        return TextUtils.isEmpty(name) || !enabled ? null : ComponentName.unflattenFromString(name);
3342687550272ba061448f5d5b914700dc335299ee7Jeff Brown    }
3352687550272ba061448f5d5b914700dc335299ee7Jeff Brown
336eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock    private ServiceInfo getServiceInfo(ComponentName name) {
337bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        try {
338eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock            return name != null ? mContext.getPackageManager().getServiceInfo(name, 0) : null;
339bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        } catch (NameNotFoundException e) {
340eb8d1be6acad180eabde84f19196b9ecaba81353John Spurlock            return null;
341bbdb062d98275f6833ebc2f0998b9e2a6534cecbJohn Spurlock        }
342f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
343f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
34462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private void startDreamLocked(final ComponentName name,
3452687550272ba061448f5d5b914700dc335299ee7Jeff Brown            final boolean isTest, final boolean canDoze, final int userId) {
34662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (Objects.equal(mCurrentDreamName, name)
34762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                && mCurrentDreamIsTest == isTest
3482687550272ba061448f5d5b914700dc335299ee7Jeff Brown                && mCurrentDreamCanDoze == canDoze
34962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                && mCurrentDreamUserId == userId) {
35062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            return;
35162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
35262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
353f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown        stopDreamLocked(true /*immediate*/);
35462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
355f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown        Slog.i(TAG, "Entering dreamland.");
35662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
35762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        final Binder newToken = new Binder();
35862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamToken = newToken;
35962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamName = name;
36062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamIsTest = isTest;
3612687550272ba061448f5d5b914700dc335299ee7Jeff Brown        mCurrentDreamCanDoze = canDoze;
36262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamUserId = userId;
36362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
36462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mHandler.post(new Runnable() {
36562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            @Override
36662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            public void run() {
3672687550272ba061448f5d5b914700dc335299ee7Jeff Brown                mController.startDream(newToken, name, isTest, canDoze, userId);
36862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
36962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        });
37062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
37162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
372f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown    private void stopDreamLocked(final boolean immediate) {
37362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (mCurrentDreamToken != null) {
374f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown            if (immediate) {
375f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                Slog.i(TAG, "Leaving dreamland.");
376f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                cleanupDreamLocked();
377f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown            } else if (mCurrentDreamIsWaking) {
378f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                return; // already waking
379f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown            } else {
380f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                Slog.i(TAG, "Gently waking up from dream.");
381f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                mCurrentDreamIsWaking = true;
382f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown            }
38362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
38462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            mHandler.post(new Runnable() {
38562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                @Override
38662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                public void run() {
387f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                    mController.stopDream(immediate);
38862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                }
38962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            });
39062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
39162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
39262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
39362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private void cleanupDreamLocked() {
39462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamToken = null;
39562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamName = null;
39662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamIsTest = false;
3972687550272ba061448f5d5b914700dc335299ee7Jeff Brown        mCurrentDreamCanDoze = false;
39862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mCurrentDreamUserId = 0;
399f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown        mCurrentDreamIsWaking = false;
4002687550272ba061448f5d5b914700dc335299ee7Jeff Brown        if (mCurrentDreamIsDozing) {
4012687550272ba061448f5d5b914700dc335299ee7Jeff Brown            mCurrentDreamIsDozing = false;
4022687550272ba061448f5d5b914700dc335299ee7Jeff Brown            mDozeWakeLock.release();
4032687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
404970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown        mCurrentDreamDozeScreenState = Display.STATE_UNKNOWN;
405970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown        mCurrentDreamDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
40662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
40762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
40862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private void checkPermission(String permission) {
40962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (mContext.checkCallingOrSelfPermission(permission)
41062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                != PackageManager.PERMISSION_GRANTED) {
41162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
41262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                    + ", must have permission " + permission);
41362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
41462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
41562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
416f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    private static String componentsToString(ComponentName[] componentNames) {
417f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        StringBuilder names = new StringBuilder();
418f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        if (componentNames != null) {
419f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            for (ComponentName componentName : componentNames) {
420f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                if (names.length() > 0) {
421f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                    names.append(',');
422f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                }
423f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                names.append(componentName.flattenToString());
424f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            }
425f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
426f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        return names.toString();
427f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
428f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
429f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    private static ComponentName[] componentsFromString(String names) {
430f5df689aa65682ce9217405e4a6b686e94129e8fJohn Spurlock        if (names == null) {
431f5df689aa65682ce9217405e4a6b686e94129e8fJohn Spurlock            return null;
432f5df689aa65682ce9217405e4a6b686e94129e8fJohn Spurlock        }
433f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        String[] namesArray = names.split(",");
434f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        ComponentName[] componentNames = new ComponentName[namesArray.length];
435f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        for (int i = 0; i < namesArray.length; i++) {
436f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            componentNames[i] = ComponentName.unflattenFromString(namesArray[i]);
437f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
438f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        return componentNames;
439f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
440f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
44162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final DreamController.Listener mControllerListener = new DreamController.Listener() {
44262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        @Override
44362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        public void onDreamStopped(Binder token) {
44462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            synchronized (mLock) {
44562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                if (mCurrentDreamToken == token) {
44662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                    cleanupDreamLocked();
447f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock                }
448f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock            }
449f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
45062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    };
451f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock
452f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    /**
453f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock     * Handler for asynchronous operations performed by the dream manager.
454f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock     * Ensures operations to {@link DreamController} are single-threaded.
455f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock     */
45662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private final class DreamHandler extends Handler {
45762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        public DreamHandler(Looper looper) {
45862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            super(looper, null, true /*async*/);
459f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock        }
460f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock    }
461567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
462567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private final class BinderService extends IDreamManager.Stub {
463567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
464567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
465567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
466567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                    != PackageManager.PERMISSION_GRANTED) {
467567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                pw.println("Permission Denial: can't dump DreamManager from from pid="
468567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                        + Binder.getCallingPid()
469567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                        + ", uid=" + Binder.getCallingUid());
470567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return;
471567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
472567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
473567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
474567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
475567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                dumpInternal(pw);
476567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
477567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
478567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
479567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
480567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
481567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
482567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public ComponentName[] getDreamComponents() {
483567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.READ_DREAM_STATE);
484567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
485567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int userId = UserHandle.getCallingUserId();
486567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
487567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
488567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return getDreamComponentsForUser(userId);
489567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
490567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
491567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
492567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
493567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
494567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
495567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void setDreamComponents(ComponentName[] componentNames) {
496567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
497567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
498567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int userId = UserHandle.getCallingUserId();
499567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
500567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
501567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                setDreamComponentsForUser(userId, componentNames);
502567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
503567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
504567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
505567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
506567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
507567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
508567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public ComponentName getDefaultDreamComponent() {
509567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.READ_DREAM_STATE);
510567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
511567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int userId = UserHandle.getCallingUserId();
512567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
513567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
514567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return getDefaultDreamComponentForUser(userId);
515567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
516567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
517567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
518567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
519567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
520567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
521567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public boolean isDreaming() {
522567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.READ_DREAM_STATE);
523567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
524567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
525567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
526567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return isDreamingInternal();
527567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
528567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
529567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
530567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
531567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
532567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
533567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void dream() {
534567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
535567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
536567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
537567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
538567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                requestDreamInternal();
539567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
540567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
541567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
542567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
543567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
544567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
545567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void testDream(ComponentName dream) {
546567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (dream == null) {
547567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                throw new IllegalArgumentException("dream must not be null");
548567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
549567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
550567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
551567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int callingUserId = UserHandle.getCallingUserId();
552567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final int currentUserId = ActivityManager.getCurrentUser();
553567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (callingUserId != currentUserId) {
554567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                // This check is inherently prone to races but at least it's something.
555567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Slog.w(TAG, "Aborted attempt to start a test dream while a different "
556567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                        + " user is active: callingUserId=" + callingUserId
557567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                        + ", currentUserId=" + currentUserId);
558567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                return;
559567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
560567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
561567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
562567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                testDreamInternal(dream, callingUserId);
563567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
564567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
565567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
566567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
567567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
568567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
569567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public void awaken() {
570567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
571567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
572567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
573567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
574567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                requestAwakenInternal();
575567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
576567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
577567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
578567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
579567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
580567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override // Binder call
581f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown        public void finishSelf(IBinder token, boolean immediate) {
582567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            // Requires no permission, called by Dream from an arbitrary process.
583567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            if (token == null) {
584567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                throw new IllegalArgumentException("token must not be null");
585567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
586567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
587567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            final long ident = Binder.clearCallingIdentity();
588567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            try {
589f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                finishSelfInternal(token, immediate);
590567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            } finally {
591567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown                Binder.restoreCallingIdentity(ident);
592567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            }
593567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
5942687550272ba061448f5d5b914700dc335299ee7Jeff Brown
5952687550272ba061448f5d5b914700dc335299ee7Jeff Brown        @Override // Binder call
596970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown        public void startDozing(IBinder token, int screenState, int screenBrightness) {
5972687550272ba061448f5d5b914700dc335299ee7Jeff Brown            // Requires no permission, called by Dream from an arbitrary process.
5982687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (token == null) {
5992687550272ba061448f5d5b914700dc335299ee7Jeff Brown                throw new IllegalArgumentException("token must not be null");
6002687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
6012687550272ba061448f5d5b914700dc335299ee7Jeff Brown
6022687550272ba061448f5d5b914700dc335299ee7Jeff Brown            final long ident = Binder.clearCallingIdentity();
6032687550272ba061448f5d5b914700dc335299ee7Jeff Brown            try {
604970d4132ea28e748c1010be39450a98bbf7466f3Jeff Brown                startDozingInternal(token, screenState, screenBrightness);
6052687550272ba061448f5d5b914700dc335299ee7Jeff Brown            } finally {
6062687550272ba061448f5d5b914700dc335299ee7Jeff Brown                Binder.restoreCallingIdentity(ident);
6072687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
6082687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
6092687550272ba061448f5d5b914700dc335299ee7Jeff Brown
6102687550272ba061448f5d5b914700dc335299ee7Jeff Brown        @Override // Binder call
6112687550272ba061448f5d5b914700dc335299ee7Jeff Brown        public void stopDozing(IBinder token) {
6122687550272ba061448f5d5b914700dc335299ee7Jeff Brown            // Requires no permission, called by Dream from an arbitrary process.
6132687550272ba061448f5d5b914700dc335299ee7Jeff Brown            if (token == null) {
6142687550272ba061448f5d5b914700dc335299ee7Jeff Brown                throw new IllegalArgumentException("token must not be null");
6152687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
6162687550272ba061448f5d5b914700dc335299ee7Jeff Brown
6172687550272ba061448f5d5b914700dc335299ee7Jeff Brown            final long ident = Binder.clearCallingIdentity();
6182687550272ba061448f5d5b914700dc335299ee7Jeff Brown            try {
6192687550272ba061448f5d5b914700dc335299ee7Jeff Brown                stopDozingInternal(token);
6202687550272ba061448f5d5b914700dc335299ee7Jeff Brown            } finally {
6212687550272ba061448f5d5b914700dc335299ee7Jeff Brown                Binder.restoreCallingIdentity(ident);
6222687550272ba061448f5d5b914700dc335299ee7Jeff Brown            }
6232687550272ba061448f5d5b914700dc335299ee7Jeff Brown        }
624567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
625567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
626567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    private final class LocalService extends DreamManagerInternal {
627567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override
6282687550272ba061448f5d5b914700dc335299ee7Jeff Brown        public void startDream(boolean doze) {
6292687550272ba061448f5d5b914700dc335299ee7Jeff Brown            startDreamInternal(doze);
630567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
631567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
632567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override
633f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown        public void stopDream(boolean immediate) {
634f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown            stopDreamInternal(immediate);
635567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
636567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown
637567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        @Override
638567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        public boolean isDreaming() {
639567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown            return isDreamingInternal();
640567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown        }
641567f7ca424280ae957b04d4f3df690055f2d41dfJeff Brown    }
6422687550272ba061448f5d5b914700dc335299ee7Jeff Brown
643bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock    private final Runnable mSystemPropertiesChanged = new Runnable() {
644bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock        @Override
645bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock        public void run() {
646bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock            if (DEBUG) Slog.d(TAG, "System properties changed");
647f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown            synchronized (mLock) {
648bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock                if (mCurrentDreamName != null && mCurrentDreamCanDoze
649bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock                        && !mCurrentDreamName.equals(getDozeComponent())) {
650f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                    // May have updated the doze component, wake up
651f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown                    mPowerManager.wakeUp(SystemClock.uptimeMillis());
652bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock                }
653bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock            }
654bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock        }
655bf370992508c55d1f2493923bdc1834a0710e4baJohn Spurlock    };
656f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock}
657