1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.dreams;
18 
19 import static android.Manifest.permission.BIND_DREAM_SERVICE;
20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
23 import static android.service.dreams.Flags.dreamHandlesBeingObscured;
24 
25 import static com.android.server.wm.ActivityInterceptorCallback.DREAM_MANAGER_ORDERED_ID;
26 
27 import android.annotation.IntDef;
28 import android.annotation.NonNull;
29 import android.annotation.Nullable;
30 import android.app.ActivityManager;
31 import android.app.IAppTask;
32 import android.app.TaskInfo;
33 import android.content.BroadcastReceiver;
34 import android.content.ComponentName;
35 import android.content.ContentResolver;
36 import android.content.Context;
37 import android.content.Intent;
38 import android.content.IntentFilter;
39 import android.content.pm.ActivityInfo;
40 import android.content.pm.PackageManager;
41 import android.content.pm.PackageManager.NameNotFoundException;
42 import android.content.pm.PackageManagerInternal;
43 import android.content.pm.ServiceInfo;
44 import android.database.ContentObserver;
45 import android.hardware.display.AmbientDisplayConfiguration;
46 import android.net.Uri;
47 import android.os.BatteryManager;
48 import android.os.BatteryManagerInternal;
49 import android.os.Binder;
50 import android.os.Build;
51 import android.os.Handler;
52 import android.os.IBinder;
53 import android.os.Looper;
54 import android.os.PowerManager;
55 import android.os.PowerManagerInternal;
56 import android.os.RemoteException;
57 import android.os.ResultReceiver;
58 import android.os.ShellCallback;
59 import android.os.SystemClock;
60 import android.os.SystemProperties;
61 import android.os.UserHandle;
62 import android.os.UserManager;
63 import android.provider.Settings;
64 import android.service.dreams.DreamManagerInternal;
65 import android.service.dreams.DreamService;
66 import android.service.dreams.IDreamManager;
67 import android.util.Slog;
68 import android.view.Display;
69 
70 import com.android.internal.R;
71 import com.android.internal.annotations.GuardedBy;
72 import com.android.internal.annotations.VisibleForTesting;
73 import com.android.internal.logging.UiEventLogger;
74 import com.android.internal.logging.UiEventLoggerImpl;
75 import com.android.internal.util.DumpUtils;
76 import com.android.server.FgThread;
77 import com.android.server.LocalServices;
78 import com.android.server.SystemService;
79 import com.android.server.input.InputManagerInternal;
80 import com.android.server.pm.UserManagerInternal;
81 import com.android.server.wm.ActivityInterceptorCallback;
82 import com.android.server.wm.ActivityTaskManagerInternal;
83 
84 import java.io.FileDescriptor;
85 import java.io.PrintWriter;
86 import java.lang.annotation.Retention;
87 import java.lang.annotation.RetentionPolicy;
88 import java.util.ArrayList;
89 import java.util.List;
90 import java.util.Objects;
91 import java.util.concurrent.CopyOnWriteArrayList;
92 import java.util.function.Consumer;
93 
94 /**
95  * Service api for managing dreams.
96  *
97  * @hide
98  */
99 public final class DreamManagerService extends SystemService {
100     private static final boolean DEBUG = false;
101     private static final String TAG = "DreamManagerService";
102 
103     private static final String DOZE_WAKE_LOCK_TAG = "dream:doze";
104     private static final String DREAM_WAKE_LOCK_TAG = "dream:dream";
105 
106     /** Constants for the when to activate dreams. */
107     @Retention(RetentionPolicy.SOURCE)
108     @IntDef({DREAM_ON_DOCK, DREAM_ON_CHARGE, DREAM_ON_DOCK_OR_CHARGE})
109     public @interface WhenToDream {}
110     private static final int DREAM_DISABLED = 0x0;
111     private static final int DREAM_ON_DOCK = 0x1;
112     private static final int DREAM_ON_CHARGE = 0x2;
113     private static final int DREAM_ON_DOCK_OR_CHARGE = 0x3;
114 
115     private final Object mLock = new Object();
116 
117     private final Context mContext;
118     private final Handler mHandler;
119     private final DreamController mController;
120     private final PowerManager mPowerManager;
121     private final PowerManagerInternal mPowerManagerInternal;
122     private final BatteryManagerInternal mBatteryManagerInternal;
123     private final PowerManager.WakeLock mDozeWakeLock;
124     private final ActivityTaskManagerInternal mAtmInternal;
125     private final PackageManagerInternal mPmInternal;
126     private final UserManager mUserManager;
127     private final UiEventLogger mUiEventLogger;
128     private final DreamUiEventLogger mDreamUiEventLogger;
129     private final ComponentName mAmbientDisplayComponent;
130     private final boolean mDismissDreamOnActivityStart;
131     private final boolean mDreamsOnlyEnabledForDockUser;
132     private final boolean mDreamsEnabledByDefaultConfig;
133     private final boolean mDreamsActivatedOnChargeByDefault;
134     private final boolean mDreamsActivatedOnDockByDefault;
135     private final boolean mKeepDreamingWhenUnpluggingDefault;
136     private final boolean mDreamsDisabledByAmbientModeSuppressionConfig;
137 
138     private final CopyOnWriteArrayList<DreamManagerInternal.DreamManagerStateListener>
139             mDreamManagerStateListeners = new CopyOnWriteArrayList<>();
140 
141     @GuardedBy("mLock")
142     private DreamRecord mCurrentDream;
143 
144     private boolean mForceAmbientDisplayEnabled;
145     private SettingsObserver mSettingsObserver;
146     private boolean mDreamsEnabledSetting;
147     @WhenToDream private int mWhenToDream;
148     private boolean mIsDocked;
149     private boolean mIsCharging;
150 
151     // A temporary dream component that, when present, takes precedence over user configured dream
152     // component.
153     private ComponentName mSystemDreamComponent;
154 
155     private ComponentName mDreamOverlayServiceName;
156 
157     private final AmbientDisplayConfiguration mDozeConfig;
158     private final ActivityInterceptorCallback mActivityInterceptorCallback =
159             new ActivityInterceptorCallback() {
160                 @Nullable
161                 @Override
162                 public ActivityInterceptResult onInterceptActivityLaunch(@NonNull
163                         ActivityInterceptorInfo info) {
164                     return null;
165                 }
166 
167                 @Override
168                 public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo,
169                         ActivityInterceptorInfo info) {
170                     final int activityType = taskInfo.getActivityType();
171                     final boolean activityAllowed = activityType == ACTIVITY_TYPE_HOME
172                             || activityType == ACTIVITY_TYPE_DREAM
173                             || activityType == ACTIVITY_TYPE_ASSISTANT;
174 
175                     boolean shouldRequestAwaken;
176                     synchronized (mLock) {
177                         shouldRequestAwaken = mCurrentDream != null && !mCurrentDream.isWaking
178                                 && !mCurrentDream.isDozing && !activityAllowed;
179                     }
180 
181                     if (shouldRequestAwaken) {
182                         requestAwakenInternal(
183                                 "stopping dream due to activity start: " + activityInfo.name);
184                     }
185                 }
186             };
187 
188     private final BroadcastReceiver mChargingReceiver = new BroadcastReceiver() {
189         @Override
190         public void onReceive(Context context, Intent intent) {
191             if (Flags.useBatteryChangedBroadcast()) {
192                 mIsCharging = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
193             } else {
194                 mIsCharging = (BatteryManager.ACTION_CHARGING.equals(intent.getAction()));
195             }
196         }
197     };
198 
199     private final BroadcastReceiver mDockStateReceiver = new BroadcastReceiver() {
200         @Override
201         public void onReceive(Context context, Intent intent) {
202             if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
203                 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
204                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
205                 mIsDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
206             }
207         }
208     };
209 
210     private final class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler)211         SettingsObserver(Handler handler) {
212             super(handler);
213         }
214 
215         @Override
onChange(boolean selfChange, Uri uri)216         public void onChange(boolean selfChange, Uri uri) {
217             updateWhenToDreamSettings();
218         }
219     }
220 
DreamManagerService(Context context)221     public DreamManagerService(Context context) {
222         this(context, new DreamHandler(FgThread.get().getLooper()));
223     }
224 
225     @VisibleForTesting
DreamManagerService(Context context, Handler handler)226     DreamManagerService(Context context, Handler handler) {
227         super(context);
228         mContext = context;
229         mHandler = handler;
230         mController = new DreamController(context, mHandler, mControllerListener);
231 
232         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
233         mPowerManagerInternal = getLocalService(PowerManagerInternal.class);
234         mAtmInternal = getLocalService(ActivityTaskManagerInternal.class);
235         mPmInternal = getLocalService(PackageManagerInternal.class);
236         mUserManager = context.getSystemService(UserManager.class);
237         mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, DOZE_WAKE_LOCK_TAG);
238         mDozeConfig = new AmbientDisplayConfiguration(mContext);
239         mUiEventLogger = new UiEventLoggerImpl();
240         mDreamUiEventLogger = new DreamUiEventLoggerImpl(
241                 mContext.getResources().getStringArray(R.array.config_loggable_dream_prefixes));
242         AmbientDisplayConfiguration adc = new AmbientDisplayConfiguration(mContext);
243         mAmbientDisplayComponent = ComponentName.unflattenFromString(adc.ambientDisplayComponent());
244         mDreamsOnlyEnabledForDockUser =
245                 mContext.getResources().getBoolean(R.bool.config_dreamsOnlyEnabledForDockUser);
246         mDismissDreamOnActivityStart = mContext.getResources().getBoolean(
247                 R.bool.config_dismissDreamOnActivityStart);
248 
249         mDreamsEnabledByDefaultConfig = mContext.getResources().getBoolean(
250                 com.android.internal.R.bool.config_dreamsEnabledByDefault);
251         mDreamsActivatedOnChargeByDefault = mContext.getResources().getBoolean(
252                 com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
253         mDreamsActivatedOnDockByDefault = mContext.getResources().getBoolean(
254                 com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
255         mSettingsObserver = new SettingsObserver(mHandler);
256         mKeepDreamingWhenUnpluggingDefault = mContext.getResources().getBoolean(
257                 com.android.internal.R.bool.config_keepDreamingWhenUnplugging);
258         mDreamsDisabledByAmbientModeSuppressionConfig = mContext.getResources().getBoolean(
259                 com.android.internal.R.bool.config_dreamsDisabledByAmbientModeSuppressionConfig);
260 
261         if (Flags.useBatteryChangedBroadcast()) {
262             mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
263         } else {
264             mBatteryManagerInternal = null;
265         }
266     }
267 
268     @Override
onStart()269     public void onStart() {
270         publishBinderService(DreamService.DREAM_SERVICE, new BinderService());
271         publishLocalService(DreamManagerInternal.class, new LocalService());
272     }
273 
274     @Override
onBootPhase(int phase)275     public void onBootPhase(int phase) {
276         if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
277             if (Build.IS_DEBUGGABLE) {
278                 SystemProperties.addChangeCallback(mSystemPropertiesChanged);
279             }
280 
281             mContext.getContentResolver().registerContentObserver(
282                     Settings.Secure.getUriFor(Settings.Secure.DOZE_DOUBLE_TAP_GESTURE), false,
283                     mDozeEnabledObserver, UserHandle.USER_ALL);
284             writePulseGestureEnabled();
285 
286             if (mDismissDreamOnActivityStart) {
287                 mAtmInternal.registerActivityStartInterceptor(
288                         DREAM_MANAGER_ORDERED_ID,
289                         mActivityInterceptorCallback);
290             }
291 
292             mContext.registerReceiver(
293                     mDockStateReceiver, new IntentFilter(Intent.ACTION_DOCK_EVENT));
294 
295             IntentFilter chargingIntentFilter = new IntentFilter();
296             if (Flags.useBatteryChangedBroadcast()) {
297                 chargingIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
298                 chargingIntentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
299             } else {
300                 chargingIntentFilter.addAction(BatteryManager.ACTION_CHARGING);
301                 chargingIntentFilter.addAction(BatteryManager.ACTION_DISCHARGING);
302             }
303             mContext.registerReceiver(mChargingReceiver, chargingIntentFilter);
304 
305             mSettingsObserver = new SettingsObserver(mHandler);
306             mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
307                             Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
308                     false, mSettingsObserver, UserHandle.USER_ALL);
309             mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
310                             Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
311                     false, mSettingsObserver, UserHandle.USER_ALL);
312             mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
313                             Settings.Secure.SCREENSAVER_ENABLED),
314                     false, mSettingsObserver, UserHandle.USER_ALL);
315 
316             // We don't get an initial broadcast for the batter state, so we have to initialize
317             // directly from BatteryManager.
318             mIsCharging = mContext.getSystemService(BatteryManager.class).isCharging();
319 
320             updateWhenToDreamSettings();
321         }
322     }
323 
324     @Override
onUserSwitching(@ullable TargetUser from, @NonNull TargetUser to)325     public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
326         updateWhenToDreamSettings();
327 
328         mHandler.post(() -> {
329             writePulseGestureEnabled();
330             synchronized (mLock) {
331                 stopDreamLocked(false /*immediate*/, "user switched");
332             }
333         });
334     }
335 
dumpInternal(PrintWriter pw)336     private void dumpInternal(PrintWriter pw) {
337         synchronized (mLock) {
338             pw.println("DREAM MANAGER (dumpsys dreams)");
339             pw.println();
340             pw.println("mCurrentDream=" + mCurrentDream);
341             pw.println("mForceAmbientDisplayEnabled=" + mForceAmbientDisplayEnabled);
342             pw.println("mDreamsOnlyEnabledForDockUser=" + mDreamsOnlyEnabledForDockUser);
343             pw.println("mDreamsEnabledSetting=" + mDreamsEnabledSetting);
344             pw.println("mDreamsActivatedOnDockByDefault=" + mDreamsActivatedOnDockByDefault);
345             pw.println("mDreamsActivatedOnChargeByDefault=" + mDreamsActivatedOnChargeByDefault);
346             pw.println("mIsDocked=" + mIsDocked);
347             pw.println("mIsCharging=" + mIsCharging);
348             pw.println("mWhenToDream=" + mWhenToDream);
349             pw.println("mKeepDreamingWhenUnpluggingDefault=" + mKeepDreamingWhenUnpluggingDefault);
350             pw.println("getDozeComponent()=" + getDozeComponent());
351             pw.println("mDreamOverlayServiceName="
352                     + ComponentName.flattenToShortString(mDreamOverlayServiceName));
353             pw.println();
354 
355             DumpUtils.dumpAsync(mHandler, (pw1, prefix) -> mController.dump(pw1), pw, "", 200);
356         }
357     }
358 
updateWhenToDreamSettings()359     private void updateWhenToDreamSettings() {
360         synchronized (mLock) {
361             final ContentResolver resolver = mContext.getContentResolver();
362 
363             final int activateWhenCharging = (Settings.Secure.getIntForUser(resolver,
364                     Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
365                     mDreamsActivatedOnChargeByDefault ? 1 : 0,
366                     UserHandle.USER_CURRENT) != 0) ? DREAM_ON_CHARGE : DREAM_DISABLED;
367             final int activateWhenDocked = (Settings.Secure.getIntForUser(resolver,
368                     Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
369                     mDreamsActivatedOnDockByDefault ? 1 : 0,
370                     UserHandle.USER_CURRENT) != 0) ? DREAM_ON_DOCK : DREAM_DISABLED;
371             mWhenToDream = activateWhenCharging + activateWhenDocked;
372 
373             mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
374                     Settings.Secure.SCREENSAVER_ENABLED,
375                     mDreamsEnabledByDefaultConfig ? 1 : 0,
376                     UserHandle.USER_CURRENT) != 0);
377         }
378     }
379 
reportKeepDreamingWhenUnpluggingChanged(boolean keepDreaming)380     private void reportKeepDreamingWhenUnpluggingChanged(boolean keepDreaming) {
381         notifyDreamStateListeners(
382                 listener -> listener.onKeepDreamingWhenUnpluggingChanged(keepDreaming));
383     }
384 
reportDreamingStarted()385     private void reportDreamingStarted() {
386         notifyDreamStateListeners(listener -> listener.onDreamingStarted());
387     }
388 
reportDreamingStopped()389     private void reportDreamingStopped() {
390         notifyDreamStateListeners(listener -> listener.onDreamingStopped());
391     }
392 
notifyDreamStateListeners( Consumer<DreamManagerInternal.DreamManagerStateListener> notifier)393     private void notifyDreamStateListeners(
394             Consumer<DreamManagerInternal.DreamManagerStateListener> notifier) {
395         mHandler.post(() -> {
396             for (DreamManagerInternal.DreamManagerStateListener listener
397                     : mDreamManagerStateListeners) {
398                 notifier.accept(listener);
399             }
400         });
401     }
402 
403     /** Whether a real dream is occurring. */
isDreamingInternal()404     private boolean isDreamingInternal() {
405         synchronized (mLock) {
406             return mCurrentDream != null && !mCurrentDream.isPreview
407                     && !mCurrentDream.isWaking;
408         }
409     }
410 
411     /** Whether a doze is occurring. */
isDozingInternal()412     private boolean isDozingInternal() {
413         synchronized (mLock) {
414             return mCurrentDream != null && mCurrentDream.isDozing;
415         }
416     }
417 
418     /** Whether a real dream, or a dream preview is occurring. */
isDreamingOrInPreviewInternal()419     private boolean isDreamingOrInPreviewInternal() {
420         synchronized (mLock) {
421             return mCurrentDream != null && !mCurrentDream.isWaking;
422         }
423     }
424 
425     /** Whether dreaming can start given user settings and the current dock/charge state. */
canStartDreamingInternal(boolean isScreenOn)426     private boolean canStartDreamingInternal(boolean isScreenOn) {
427         synchronized (mLock) {
428             // Can't start dreaming if we are already dreaming and the dream has focus. If we are
429             // dreaming but the dream does not have focus, then the dream can be brought to the
430             // front so it does have focus.
431             if (isScreenOn && isDreamingInternal() && dreamIsFrontmost()) {
432                 return false;
433             }
434 
435             if (!mDreamsEnabledSetting) {
436                 return false;
437             }
438 
439             if (!dreamsEnabledForUser(ActivityManager.getCurrentUser())) {
440                 return false;
441             }
442 
443             if (!mUserManager.isUserUnlocked()) {
444                 return false;
445             }
446 
447             if (mDreamsDisabledByAmbientModeSuppressionConfig
448                     && mPowerManagerInternal.isAmbientDisplaySuppressed()) {
449                 // Don't dream if Bedtime (or something else) is suppressing ambient.
450                 Slog.i(TAG, "Can't start dreaming because ambient is suppressed.");
451                 return false;
452             }
453 
454             if ((mWhenToDream & DREAM_ON_CHARGE) == DREAM_ON_CHARGE) {
455                 return mIsCharging;
456             }
457 
458             if ((mWhenToDream & DREAM_ON_DOCK) == DREAM_ON_DOCK) {
459                 return mIsDocked;
460             }
461 
462             return false;
463         }
464     }
465 
dreamIsFrontmost()466     private boolean dreamIsFrontmost() {
467         // Dreams were always considered frontmost before they began tracking whether they are
468         // obscured.
469         return !dreamHandlesBeingObscured() || mController.dreamIsFrontmost();
470     }
471 
requestStartDreamFromShell()472     protected void requestStartDreamFromShell() {
473         requestDreamInternal();
474     }
475 
requestDreamInternal()476     private void requestDreamInternal() {
477         if (isDreamingInternal() && !dreamIsFrontmost() && mController.bringDreamToFront()) {
478             return;
479         }
480 
481         // Ask the power manager to nap.  It will eventually call back into
482         // startDream() if/when it is appropriate to start dreaming.
483         // Because napping could cause the screen to turn off immediately if the dream
484         // cannot be started, we keep one eye open and gently poke user activity.
485         long time = SystemClock.uptimeMillis();
486         mPowerManager.userActivity(time, /* noChangeLights= */ true);
487         mPowerManagerInternal.nap(time, /* allowWake= */ true);
488     }
489 
requestAwakenInternal(String reason)490     private void requestAwakenInternal(String reason) {
491         // Treat an explicit request to awaken as user activity so that the
492         // device doesn't immediately go to sleep if the timeout expired,
493         // for example when being undocked.
494         long time = SystemClock.uptimeMillis();
495         mPowerManager.userActivity(time, false /*noChangeLights*/);
496         stopDreamInternal(false /*immediate*/, reason);
497     }
498 
finishSelfInternal(IBinder token, boolean immediate)499     private void finishSelfInternal(IBinder token, boolean immediate) {
500         if (DEBUG) {
501             Slog.d(TAG, "Dream finished: " + token + ", immediate=" + immediate);
502         }
503 
504         // Note that a dream finishing and self-terminating is not
505         // itself considered user activity.  If the dream is ending because
506         // the user interacted with the device then user activity will already
507         // have been poked so the device will stay awake a bit longer.
508         // If the dream is ending on its own for other reasons and no wake
509         // locks are held and the user activity timeout has expired then the
510         // device may simply go to sleep.
511         synchronized (mLock) {
512             if (mCurrentDream != null && mCurrentDream.token == token) {
513                 stopDreamLocked(immediate, "finished self");
514             }
515         }
516     }
517 
testDreamInternal(ComponentName dream, int userId)518     private void testDreamInternal(ComponentName dream, int userId) {
519         synchronized (mLock) {
520             startDreamLocked(dream, true /*isPreviewMode*/, false /*canDoze*/, userId,
521                     "test dream" /*reason*/);
522         }
523     }
524 
startDreamInternal(boolean doze, String reason)525     private void startDreamInternal(boolean doze, String reason) {
526         final int userId = ActivityManager.getCurrentUser();
527         final ComponentName dream = chooseDreamForUser(doze, userId);
528         if (dream != null) {
529             synchronized (mLock) {
530                 startDreamLocked(dream, false /*isPreviewMode*/, doze, userId, reason);
531             }
532         }
533     }
534 
requestStopDreamFromShell()535     protected void requestStopDreamFromShell() {
536         stopDreamInternal(false, "stopping dream from shell");
537     }
538 
stopDreamInternal(boolean immediate, String reason)539     private void stopDreamInternal(boolean immediate, String reason) {
540         synchronized (mLock) {
541             stopDreamLocked(immediate, reason);
542         }
543     }
544 
startDozingInternal(IBinder token, int screenState, @Display.StateReason int reason, int screenBrightness)545     private void startDozingInternal(IBinder token, int screenState,
546             @Display.StateReason int reason, int screenBrightness) {
547         if (DEBUG) {
548             Slog.d(TAG, "Dream requested to start dozing: " + token
549                     + ", screenState=" + screenState
550                     + ", screenBrightness=" + screenBrightness);
551         }
552 
553         synchronized (mLock) {
554             if (mCurrentDream != null && mCurrentDream.token == token && mCurrentDream.canDoze) {
555                 mCurrentDream.dozeScreenState = screenState;
556                 mCurrentDream.dozeScreenBrightness = screenBrightness;
557                 mPowerManagerInternal.setDozeOverrideFromDreamManager(
558                         screenState, reason, screenBrightness);
559                 if (!mCurrentDream.isDozing) {
560                     mCurrentDream.isDozing = true;
561                     mDozeWakeLock.acquire();
562                 }
563             }
564         }
565     }
566 
stopDozingInternal(IBinder token)567     private void stopDozingInternal(IBinder token) {
568         if (DEBUG) {
569             Slog.d(TAG, "Dream requested to stop dozing: " + token);
570         }
571 
572         synchronized (mLock) {
573             if (mCurrentDream != null && mCurrentDream.token == token && mCurrentDream.isDozing) {
574                 mCurrentDream.isDozing = false;
575                 mDozeWakeLock.release();
576                 mPowerManagerInternal.setDozeOverrideFromDreamManager(
577                         Display.STATE_UNKNOWN,
578                         Display.STATE_REASON_DREAM_MANAGER,
579                         PowerManager.BRIGHTNESS_DEFAULT);
580             }
581         }
582     }
583 
forceAmbientDisplayEnabledInternal(boolean enabled)584     private void forceAmbientDisplayEnabledInternal(boolean enabled) {
585         if (DEBUG) {
586             Slog.d(TAG, "Force ambient display enabled: " + enabled);
587         }
588 
589         synchronized (mLock) {
590             mForceAmbientDisplayEnabled = enabled;
591         }
592     }
593 
594     /**
595      * If doze is true, returns the doze component for the user.
596      * Otherwise, returns the system dream component, if present.
597      * Otherwise, returns the first valid user configured dream component.
598      */
chooseDreamForUser(boolean doze, int userId)599     private ComponentName chooseDreamForUser(boolean doze, int userId) {
600         if (doze) {
601             ComponentName dozeComponent = getDozeComponent(userId);
602             return validateDream(dozeComponent) ? dozeComponent : null;
603         }
604 
605         if (mSystemDreamComponent != null) {
606             return mSystemDreamComponent;
607         }
608 
609         ComponentName[] dreams = getDreamComponentsForUser(userId);
610         return dreams != null && dreams.length != 0 ? dreams[0] : null;
611     }
612 
validateDream(ComponentName component)613     private boolean validateDream(ComponentName component) {
614         if (component == null) return false;
615         final ServiceInfo serviceInfo = getServiceInfo(component);
616         if (serviceInfo == null) {
617             Slog.w(TAG, "Dream " + component + " does not exist");
618             return false;
619         } else if (serviceInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP
620                 && !BIND_DREAM_SERVICE.equals(serviceInfo.permission)) {
621             Slog.w(TAG, "Dream " + component
622                     + " is not available because its manifest is missing the " + BIND_DREAM_SERVICE
623                     + " permission on the dream service declaration.");
624             return false;
625         }
626         return true;
627     }
628 
getDreamComponentsForUser(int userId)629     private ComponentName[] getDreamComponentsForUser(int userId) {
630         if (!dreamsEnabledForUser(userId)) {
631             // Don't return any dream components if the user is not allowed to dream.
632             return null;
633         }
634 
635         String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
636                 Settings.Secure.SCREENSAVER_COMPONENTS,
637                 userId);
638         ComponentName[] components = componentsFromString(names);
639 
640         // first, ensure components point to valid services
641         List<ComponentName> validComponents = new ArrayList<>();
642         if (components != null) {
643             for (ComponentName component : components) {
644                 if (validateDream(component)) {
645                     validComponents.add(component);
646                 }
647             }
648         }
649 
650         // fallback to the default dream component if necessary
651         if (validComponents.isEmpty()) {
652             ComponentName defaultDream = getDefaultDreamComponentForUser(userId);
653             if (defaultDream != null) {
654                 Slog.w(TAG, "Falling back to default dream " + defaultDream);
655                 validComponents.add(defaultDream);
656             }
657         }
658         return validComponents.toArray(new ComponentName[validComponents.size()]);
659     }
660 
setDreamComponentsForUser(int userId, ComponentName[] componentNames)661     private void setDreamComponentsForUser(int userId, ComponentName[] componentNames) {
662         Settings.Secure.putStringForUser(mContext.getContentResolver(),
663                 Settings.Secure.SCREENSAVER_COMPONENTS,
664                 componentsToString(componentNames),
665                 userId);
666     }
667 
setSystemDreamComponentInternal(ComponentName componentName)668     private void setSystemDreamComponentInternal(ComponentName componentName) {
669         synchronized (mLock) {
670             if (Objects.equals(mSystemDreamComponent, componentName)) {
671                 return;
672             }
673 
674             mSystemDreamComponent = componentName;
675             reportKeepDreamingWhenUnpluggingChanged(shouldKeepDreamingWhenUnplugging());
676             // Switch dream if currently dreaming and not dozing.
677             if (isDreamingInternal() && !isDozingInternal()) {
678                 startDreamInternal(false /*doze*/, (mSystemDreamComponent == null ? "clear" : "set")
679                         + " system dream component" /*reason*/);
680             }
681         }
682     }
683 
shouldKeepDreamingWhenUnplugging()684     private boolean shouldKeepDreamingWhenUnplugging() {
685         return mKeepDreamingWhenUnpluggingDefault && mSystemDreamComponent == null;
686     }
687 
getDefaultDreamComponentForUser(int userId)688     private ComponentName getDefaultDreamComponentForUser(int userId) {
689         String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
690                 Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
691                 userId);
692         return name == null ? null : ComponentName.unflattenFromString(name);
693     }
694 
getDozeComponent()695     private ComponentName getDozeComponent() {
696         return getDozeComponent(ActivityManager.getCurrentUser());
697     }
698 
getDozeComponent(int userId)699     private ComponentName getDozeComponent(int userId) {
700         if (mForceAmbientDisplayEnabled || mDozeConfig.enabled(userId)) {
701             return ComponentName.unflattenFromString(mDozeConfig.ambientDisplayComponent());
702         } else {
703             return null;
704         }
705 
706     }
707 
dreamsEnabledForUser(int userId)708     private boolean dreamsEnabledForUser(int userId) {
709         if (!mDreamsOnlyEnabledForDockUser) return true;
710         if (userId < 0) return false;
711         final int mainUserId = LocalServices.getService(UserManagerInternal.class).getMainUserId();
712         return userId == mainUserId;
713     }
714 
getServiceInfo(ComponentName name)715     private ServiceInfo getServiceInfo(ComponentName name) {
716         try {
717             return name != null ? mContext.getPackageManager().getServiceInfo(name,
718                     PackageManager.MATCH_DEBUG_TRIAGED_MISSING) : null;
719         } catch (NameNotFoundException e) {
720             return null;
721         }
722     }
723 
724     @GuardedBy("mLock")
startDreamLocked(final ComponentName name, final boolean isPreviewMode, final boolean canDoze, final int userId, final String reason)725     private void startDreamLocked(final ComponentName name,
726             final boolean isPreviewMode, final boolean canDoze, final int userId,
727             final String reason) {
728         if (mCurrentDream != null
729                 && !mCurrentDream.isWaking
730                 && Objects.equals(mCurrentDream.name, name)
731                 && mCurrentDream.isPreview == isPreviewMode
732                 && mCurrentDream.canDoze == canDoze
733                 && mCurrentDream.userId == userId) {
734             Slog.i(TAG, "Already in target dream.");
735             return;
736         }
737 
738         Slog.i(TAG, "Entering dreamland.");
739 
740         if (mCurrentDream != null && mCurrentDream.isDozing) {
741             stopDozingInternal(mCurrentDream.token);
742         }
743 
744         mCurrentDream = new DreamRecord(name, userId, isPreviewMode, canDoze);
745 
746         if (!mCurrentDream.name.equals(mAmbientDisplayComponent)) {
747             // TODO(b/213906448): Remove when metrics based on new atom are fully rolled out.
748             mUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_START);
749             mDreamUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_START,
750                     mCurrentDream.name.flattenToString());
751         }
752 
753         PowerManager.WakeLock wakeLock = mPowerManager
754                 .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, DREAM_WAKE_LOCK_TAG);
755         final Binder dreamToken = mCurrentDream.token;
756         mHandler.post(wakeLock.wrap(() -> {
757             mAtmInternal.notifyActiveDreamChanged(name);
758             mController.startDream(dreamToken, name, isPreviewMode, canDoze, userId, wakeLock,
759                     mDreamOverlayServiceName, reason);
760         }));
761     }
762 
763     @GuardedBy("mLock")
stopDreamLocked(final boolean immediate, String reason)764     private void stopDreamLocked(final boolean immediate, String reason) {
765         if (mCurrentDream != null) {
766             if (immediate) {
767                 Slog.i(TAG, "Leaving dreamland.");
768                 cleanupDreamLocked();
769             } else if (mCurrentDream.isWaking) {
770                 return; // already waking
771             } else {
772                 Slog.i(TAG, "Gently waking up from dream.");
773                 mCurrentDream.isWaking = true;
774             }
775 
776             mHandler.post(() -> mController.stopDream(immediate, reason));
777         }
778     }
779 
780     @GuardedBy("mLock")
cleanupDreamLocked()781     private void cleanupDreamLocked() {
782         mHandler.post(() -> mAtmInternal.notifyActiveDreamChanged(null));
783 
784         if (mCurrentDream == null) {
785             return;
786         }
787 
788         if (!mCurrentDream.name.equals(mAmbientDisplayComponent)) {
789             // TODO(b/213906448): Remove when metrics based on new atom are fully rolled out.
790             mUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_STOP);
791             mDreamUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_STOP,
792                     mCurrentDream.name.flattenToString());
793         }
794         if (mCurrentDream.isDozing) {
795             mDozeWakeLock.release();
796         }
797         mCurrentDream = null;
798     }
799 
checkPermission(String permission)800     private void checkPermission(String permission) {
801         if (mContext.checkCallingOrSelfPermission(permission)
802                 != PackageManager.PERMISSION_GRANTED) {
803             throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
804                     + ", must have permission " + permission);
805         }
806     }
807 
writePulseGestureEnabled()808     private void writePulseGestureEnabled() {
809         ComponentName name = getDozeComponent();
810         boolean dozeEnabled = validateDream(name);
811         LocalServices.getService(InputManagerInternal.class).setPulseGestureEnabled(dozeEnabled);
812     }
813 
componentsToString(ComponentName[] componentNames)814     private static String componentsToString(ComponentName[] componentNames) {
815         if (componentNames == null) {
816             return null;
817         }
818         StringBuilder names = new StringBuilder();
819         for (ComponentName componentName : componentNames) {
820             if (names.length() > 0) {
821                 names.append(',');
822             }
823             names.append(componentName.flattenToString());
824         }
825         return names.toString();
826     }
827 
componentsFromString(String names)828     private static ComponentName[] componentsFromString(String names) {
829         if (names == null) {
830             return null;
831         }
832         String[] namesArray = names.split(",");
833         ComponentName[] componentNames = new ComponentName[namesArray.length];
834         for (int i = 0; i < namesArray.length; i++) {
835             componentNames[i] = ComponentName.unflattenFromString(namesArray[i]);
836         }
837         return componentNames;
838     }
839 
840     private final DreamController.Listener mControllerListener = new DreamController.Listener() {
841         @Override
842         public void onDreamStarted(Binder token) {
843             // Note that this event is distinct from DreamManagerService#startDreamLocked as it
844             // tracks the DreamService attach point from DreamController, closest to the broadcast
845             // of ACTION_DREAMING_STARTED.
846 
847             reportDreamingStarted();
848         }
849 
850         @Override
851         public void onDreamStopped(Binder token) {
852             synchronized (mLock) {
853                 if (mCurrentDream != null && mCurrentDream.token == token) {
854                     cleanupDreamLocked();
855                 }
856             }
857 
858             reportDreamingStopped();
859         }
860     };
861 
862     private final ContentObserver mDozeEnabledObserver = new ContentObserver(null) {
863         @Override
864         public void onChange(boolean selfChange) {
865             writePulseGestureEnabled();
866         }
867     };
868 
869     /**
870      * Handler for asynchronous operations performed by the dream manager.
871      * Ensures operations to {@link DreamController} are single-threaded.
872      */
873     private static final class DreamHandler extends Handler {
DreamHandler(Looper looper)874         public DreamHandler(Looper looper) {
875             super(looper, null, true /*async*/);
876         }
877     }
878 
879     private final class BinderService extends IDreamManager.Stub {
880         @Override // Binder call
dump(FileDescriptor fd, PrintWriter pw, String[] args)881         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
882             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
883             final long ident = Binder.clearCallingIdentity();
884             try {
885                 dumpInternal(pw);
886             } finally {
887                 Binder.restoreCallingIdentity(ident);
888             }
889         }
890 
onShellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)891         public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
892                 @Nullable FileDescriptor err,
893                 @NonNull String[] args, @Nullable ShellCallback callback,
894                 @NonNull ResultReceiver resultReceiver) throws RemoteException {
895             new DreamShellCommand(DreamManagerService.this)
896                     .exec(this, in, out, err, args, callback, resultReceiver);
897         }
898 
899         @Override // Binder call
getDreamComponents()900         public ComponentName[] getDreamComponents() {
901             return getDreamComponentsForUser(UserHandle.getCallingUserId());
902         }
903 
904         @Override // Binder call
getDreamComponentsForUser(int userId)905         public ComponentName[] getDreamComponentsForUser(int userId) {
906             checkPermission(android.Manifest.permission.READ_DREAM_STATE);
907             userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
908                     Binder.getCallingUid(), userId, false, true, "getDreamComponents", null);
909 
910             final long ident = Binder.clearCallingIdentity();
911             try {
912                 return DreamManagerService.this.getDreamComponentsForUser(userId);
913             } finally {
914                 Binder.restoreCallingIdentity(ident);
915             }
916         }
917 
918         @Override // Binder call
setDreamComponents(ComponentName[] componentNames)919         public void setDreamComponents(ComponentName[] componentNames) {
920             checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
921 
922             final int userId = UserHandle.getCallingUserId();
923             final long ident = Binder.clearCallingIdentity();
924             try {
925                 setDreamComponentsForUser(userId, componentNames);
926             } finally {
927                 Binder.restoreCallingIdentity(ident);
928             }
929         }
930 
931         @Override // Binder call
setDreamComponentsForUser(int userId, ComponentName[] componentNames)932         public void setDreamComponentsForUser(int userId, ComponentName[] componentNames) {
933             checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
934             userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
935                     Binder.getCallingUid(), userId, false, true, "setDreamComponents", null);
936 
937             final long ident = Binder.clearCallingIdentity();
938             try {
939                 DreamManagerService.this.setDreamComponentsForUser(userId, componentNames);
940             } finally {
941                 Binder.restoreCallingIdentity(ident);
942             }
943         }
944 
945         @Override // Binder call
setSystemDreamComponent(ComponentName componentName)946         public void setSystemDreamComponent(ComponentName componentName) {
947             checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
948 
949             final long ident = Binder.clearCallingIdentity();
950             try {
951                 DreamManagerService.this.setSystemDreamComponentInternal(componentName);
952             } finally {
953                 Binder.restoreCallingIdentity(ident);
954             }
955         }
956 
957         @Override // Binder call
registerDreamOverlayService(ComponentName overlayComponent)958         public void registerDreamOverlayService(ComponentName overlayComponent) {
959             checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
960 
961             // Store the overlay service component so that it can be passed to the dream when it is
962             // invoked.
963             mDreamOverlayServiceName = overlayComponent;
964         }
965 
966         @Override // Binder call
getDefaultDreamComponentForUser(int userId)967         public ComponentName getDefaultDreamComponentForUser(int userId) {
968             checkPermission(android.Manifest.permission.READ_DREAM_STATE);
969             userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
970                     Binder.getCallingUid(), userId, false, true, "getDefaultDreamComponent", null);
971 
972             final long ident = Binder.clearCallingIdentity();
973             try {
974                 return DreamManagerService.this.getDefaultDreamComponentForUser(userId);
975             } finally {
976                 Binder.restoreCallingIdentity(ident);
977             }
978         }
979 
980         @Override // Binder call
isDreaming()981         public boolean isDreaming() {
982             checkPermission(android.Manifest.permission.READ_DREAM_STATE);
983 
984             final long ident = Binder.clearCallingIdentity();
985             try {
986                 return isDreamingInternal();
987             } finally {
988                 Binder.restoreCallingIdentity(ident);
989             }
990         }
991 
992         @Override // Binder call
isDreamingOrInPreview()993         public boolean isDreamingOrInPreview() {
994             checkPermission(android.Manifest.permission.READ_DREAM_STATE);
995 
996             final long ident = Binder.clearCallingIdentity();
997             try {
998                 return isDreamingOrInPreviewInternal();
999             } finally {
1000                 Binder.restoreCallingIdentity(ident);
1001             }
1002         }
1003 
1004 
1005         @Override // Binder call
dream()1006         public void dream() {
1007             checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
1008 
1009             final long ident = Binder.clearCallingIdentity();
1010             try {
1011                 requestDreamInternal();
1012             } finally {
1013                 Binder.restoreCallingIdentity(ident);
1014             }
1015         }
1016 
1017         @Override // Binder call
canStartDreaming(boolean isScreenOn)1018         public boolean canStartDreaming(boolean isScreenOn) {
1019             checkPermission(android.Manifest.permission.READ_DREAM_STATE);
1020 
1021             final long ident = Binder.clearCallingIdentity();
1022             try {
1023                 return canStartDreamingInternal(isScreenOn);
1024             } finally {
1025                 Binder.restoreCallingIdentity(ident);
1026             }
1027         }
1028 
1029         @Override // Binder call
testDream(int userId, ComponentName dream)1030         public void testDream(int userId, ComponentName dream) {
1031             if (dream == null) {
1032                 throw new IllegalArgumentException("dream must not be null");
1033             }
1034             checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
1035             userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
1036                     Binder.getCallingUid(), userId, false, true, "testDream", null);
1037 
1038             final int currentUserId = ActivityManager.getCurrentUser();
1039             if (userId != currentUserId) {
1040                 // This check is inherently prone to races but at least it's something.
1041                 Slog.w(TAG, "Aborted attempt to start a test dream while a different "
1042                         + " user is active: userId=" + userId
1043                         + ", currentUserId=" + currentUserId);
1044                 return;
1045             }
1046             final long ident = Binder.clearCallingIdentity();
1047             try {
1048                 testDreamInternal(dream, userId);
1049             } finally {
1050                 Binder.restoreCallingIdentity(ident);
1051             }
1052         }
1053 
1054         @Override // Binder call
awaken()1055         public void awaken() {
1056             checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
1057 
1058             final long ident = Binder.clearCallingIdentity();
1059             try {
1060                 requestAwakenInternal("request awaken");
1061             } finally {
1062                 Binder.restoreCallingIdentity(ident);
1063             }
1064         }
1065 
1066         @Override // Binder call
finishSelf(IBinder token, boolean immediate)1067         public void finishSelf(IBinder token, boolean immediate) {
1068             // Requires no permission, called by Dream from an arbitrary process.
1069             if (token == null) {
1070                 throw new IllegalArgumentException("token must not be null");
1071             }
1072 
1073             final long ident = Binder.clearCallingIdentity();
1074             try {
1075                 finishSelfInternal(token, immediate);
1076             } finally {
1077                 Binder.restoreCallingIdentity(ident);
1078             }
1079         }
1080 
1081         @Override // Binder call
startDozing( IBinder token, int screenState, @Display.StateReason int reason, int screenBrightness)1082         public void startDozing(
1083                 IBinder token, int screenState, @Display.StateReason int reason,
1084                 int screenBrightness) {
1085             // Requires no permission, called by Dream from an arbitrary process.
1086             if (token == null) {
1087                 throw new IllegalArgumentException("token must not be null");
1088             }
1089 
1090             final long ident = Binder.clearCallingIdentity();
1091             try {
1092                 startDozingInternal(token, screenState, reason, screenBrightness);
1093             } finally {
1094                 Binder.restoreCallingIdentity(ident);
1095             }
1096         }
1097 
1098         @Override // Binder call
stopDozing(IBinder token)1099         public void stopDozing(IBinder token) {
1100             // Requires no permission, called by Dream from an arbitrary process.
1101             if (token == null) {
1102                 throw new IllegalArgumentException("token must not be null");
1103             }
1104 
1105             final long ident = Binder.clearCallingIdentity();
1106             try {
1107                 stopDozingInternal(token);
1108             } finally {
1109                 Binder.restoreCallingIdentity(ident);
1110             }
1111         }
1112 
1113         @Override // Binder call
forceAmbientDisplayEnabled(boolean enabled)1114         public void forceAmbientDisplayEnabled(boolean enabled) {
1115             checkPermission(android.Manifest.permission.DEVICE_POWER);
1116 
1117             final long ident = Binder.clearCallingIdentity();
1118             try {
1119                 forceAmbientDisplayEnabledInternal(enabled);
1120             } finally {
1121                 Binder.restoreCallingIdentity(ident);
1122             }
1123         }
1124 
1125         @Override // Binder call
startDreamActivity(@onNull Intent intent)1126         public void startDreamActivity(@NonNull Intent intent) {
1127             final int callingUid = Binder.getCallingUid();
1128             final int callingPid = Binder.getCallingPid();
1129             // We post here, because startDreamActivity and setDreamAppTask have to run
1130             // synchronously and DreamController#setDreamAppTask has to run on mHandler.
1131             mHandler.post(() -> {
1132                 final Binder dreamToken;
1133                 final String dreamPackageName;
1134                 synchronized (mLock) {
1135                     if (mCurrentDream == null) {
1136                         Slog.e(TAG, "Attempt to start DreamActivity, but the device is not "
1137                                 + "dreaming. Aborting without starting the DreamActivity.");
1138                         return;
1139                     }
1140                     dreamToken = mCurrentDream.token;
1141                     dreamPackageName = mCurrentDream.name.getPackageName();
1142                 }
1143 
1144                 if (!canLaunchDreamActivity(dreamPackageName, intent.getPackage(),
1145                             callingUid)) {
1146                     Slog.e(TAG, "The dream activity can be started only when the device is dreaming"
1147                             + " and only by the active dream package.");
1148                     return;
1149                 }
1150 
1151                 final IAppTask appTask = mAtmInternal.startDreamActivity(intent, callingUid,
1152                         callingPid);
1153                 if (appTask == null) {
1154                     Slog.e(TAG, "Could not start dream activity.");
1155                     stopDreamInternal(true, "DreamActivity not started");
1156                     return;
1157                 }
1158                 mController.setDreamAppTask(dreamToken, appTask);
1159             });
1160         }
1161 
1162         @Override
setDreamIsObscured(boolean isObscured)1163         public void setDreamIsObscured(boolean isObscured) {
1164             if (!dreamHandlesBeingObscured()) {
1165                 return;
1166             }
1167 
1168             checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
1169 
1170             final long ident = Binder.clearCallingIdentity();
1171             try {
1172                 mHandler.post(() -> mController.setDreamIsObscured(isObscured));
1173             } finally {
1174                 Binder.restoreCallingIdentity(ident);
1175             }
1176         }
1177 
canLaunchDreamActivity(String dreamPackageName, String packageName, int callingUid)1178         boolean canLaunchDreamActivity(String dreamPackageName, String packageName,
1179                 int callingUid) {
1180             if (dreamPackageName == null || packageName == null) {
1181                 Slog.e(TAG, "Cannot launch dream activity due to invalid state. dream component= "
1182                         + dreamPackageName + ", packageName=" + packageName);
1183                 return false;
1184             }
1185             if (!mPmInternal.isSameApp(packageName, callingUid, UserHandle.getUserId(callingUid))) {
1186                 Slog.e(TAG, "Cannot launch dream activity because package="
1187                         + packageName + " does not match callingUid=" + callingUid);
1188                 return false;
1189             }
1190             if (packageName.equals(dreamPackageName)) {
1191                 return true;
1192             }
1193             Slog.e(TAG, "Dream packageName does not match active dream. Package " + packageName
1194                     + " does not match " + dreamPackageName);
1195             return false;
1196         }
1197 
1198     }
1199 
1200     private final class LocalService extends DreamManagerInternal {
1201         @Override
startDream(boolean doze, String reason)1202         public void startDream(boolean doze, String reason) {
1203             startDreamInternal(doze, reason);
1204         }
1205 
1206         @Override
stopDream(boolean immediate, String reason)1207         public void stopDream(boolean immediate, String reason) {
1208             stopDreamInternal(immediate, reason);
1209         }
1210 
1211         @Override
isDreaming()1212         public boolean isDreaming() {
1213             return isDreamingInternal();
1214         }
1215 
1216         @Override
canStartDreaming(boolean isScreenOn)1217         public boolean canStartDreaming(boolean isScreenOn) {
1218             return canStartDreamingInternal(isScreenOn);
1219         }
1220 
1221         @Override
requestDream()1222         public void requestDream() {
1223             requestDreamInternal();
1224         }
1225 
1226         @Override
registerDreamManagerStateListener(DreamManagerStateListener listener)1227         public void registerDreamManagerStateListener(DreamManagerStateListener listener) {
1228             mDreamManagerStateListeners.add(listener);
1229             // Initialize the listener's state.
1230             listener.onKeepDreamingWhenUnpluggingChanged(shouldKeepDreamingWhenUnplugging());
1231         }
1232 
1233         @Override
unregisterDreamManagerStateListener(DreamManagerStateListener listener)1234         public void unregisterDreamManagerStateListener(DreamManagerStateListener listener) {
1235             mDreamManagerStateListeners.remove(listener);
1236         }
1237     }
1238 
1239     private static final class DreamRecord {
1240         public final Binder token = new Binder();
1241         public final ComponentName name;
1242         public final int userId;
1243         public final boolean isPreview;
1244         public final boolean canDoze;
1245         public boolean isDozing = false;
1246         public boolean isWaking = false;
1247         public int dozeScreenState = Display.STATE_UNKNOWN;
1248         public int dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
1249 
DreamRecord(ComponentName name, int userId, boolean isPreview, boolean canDoze)1250         DreamRecord(ComponentName name, int userId, boolean isPreview, boolean canDoze) {
1251             this.name = name;
1252             this.userId = userId;
1253             this.isPreview = isPreview;
1254             this.canDoze = canDoze;
1255         }
1256 
1257         @Override
toString()1258         public String toString() {
1259             return "DreamRecord{"
1260                     + "token=" + token
1261                     + ", name=" + name
1262                     + ", userId=" + userId
1263                     + ", isPreview=" + isPreview
1264                     + ", canDoze=" + canDoze
1265                     + ", isDozing=" + isDozing
1266                     + ", isWaking=" + isWaking
1267                     + ", dozeScreenState=" + dozeScreenState
1268                     + ", dozeScreenBrightness=" + dozeScreenBrightness
1269                     + '}';
1270         }
1271     }
1272 
1273     private final Runnable mSystemPropertiesChanged = new Runnable() {
1274         @Override
1275         public void run() {
1276             if (DEBUG) Slog.d(TAG, "System properties changed");
1277             synchronized (mLock) {
1278                 if (mCurrentDream != null &&  mCurrentDream.name != null && mCurrentDream.canDoze
1279                         && !mCurrentDream.name.equals(getDozeComponent())) {
1280                     // May have updated the doze component, wake up
1281                     mPowerManager.wakeUp(SystemClock.uptimeMillis(),
1282                             "android.server.dreams:SYSPROP");
1283                 }
1284             }
1285         }
1286     };
1287 }
1288