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