blob: 20bccf19f131c33f99253722c94abdb43aa512a4 [file] [log] [blame]
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001/*
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
Jeff Browncef440f2012-09-25 18:58:48 -070017package com.android.server.dreams;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040018
John Spurlockeb8d1be2014-06-25 17:46:15 -040019import static android.Manifest.permission.BIND_DREAM_SERVICE;
20
Jeff Brown62c82e42012-09-26 01:30:41 -070021import com.android.internal.util.DumpUtils;
Jeff Brown4ccb8232014-01-16 22:16:42 -080022import com.android.server.FgThread;
Adrian Roos99182342016-06-15 15:30:46 -070023import com.android.server.LocalServices;
Jeff Brown567f7ca2014-01-30 23:38:03 -080024import com.android.server.SystemService;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040025
Jeff Brown567f7ca2014-01-30 23:38:03 -080026import android.Manifest;
Jeff Brown62c82e42012-09-26 01:30:41 -070027import android.app.ActivityManager;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040028import android.content.BroadcastReceiver;
29import android.content.ComponentName;
30import android.content.Context;
31import android.content.Intent;
32import android.content.IntentFilter;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040033import android.content.pm.PackageManager;
John Spurlockbbdb0622012-12-10 18:15:07 -050034import android.content.pm.PackageManager.NameNotFoundException;
John Spurlockeb8d1be2014-06-25 17:46:15 -040035import android.content.pm.ServiceInfo;
Adrian Roos99182342016-06-15 15:30:46 -070036import android.database.ContentObserver;
37import android.hardware.input.InputManagerInternal;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040038import android.os.Binder;
Jeff Brown26875502014-01-30 21:47:47 -080039import android.os.Build;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040040import android.os.Handler;
41import android.os.IBinder;
Jeff Brown62c82e42012-09-26 01:30:41 -070042import android.os.Looper;
43import android.os.PowerManager;
Jeff Brown970d4132014-07-19 11:33:47 -070044import android.os.PowerManagerInternal;
Jeff Brown62c82e42012-09-26 01:30:41 -070045import android.os.SystemClock;
Jeff Brown26875502014-01-30 21:47:47 -080046import android.os.SystemProperties;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040047import android.os.UserHandle;
48import android.provider.Settings;
Jeff Brown567f7ca2014-01-30 23:38:03 -080049import android.service.dreams.DreamManagerInternal;
50import android.service.dreams.DreamService;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040051import android.service.dreams.IDreamManager;
Jeff Brown26875502014-01-30 21:47:47 -080052import android.text.TextUtils;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040053import android.util.Slog;
Jeff Brown970d4132014-07-19 11:33:47 -070054import android.view.Display;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040055
56import java.io.FileDescriptor;
57import java.io.PrintWriter;
John Spurlockbbdb0622012-12-10 18:15:07 -050058import java.util.ArrayList;
59import java.util.List;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040060
Jeff Brown62c82e42012-09-26 01:30:41 -070061import libcore.util.Objects;
62
John Spurlockf4f6b4c2012-08-25 12:08:03 -040063/**
64 * Service api for managing dreams.
65 *
66 * @hide
67 */
Jeff Brown567f7ca2014-01-30 23:38:03 -080068public final class DreamManagerService extends SystemService {
Dianne Hackborn40e9f292012-11-27 19:12:23 -080069 private static final boolean DEBUG = false;
Jeff Brown62c82e42012-09-26 01:30:41 -070070 private static final String TAG = "DreamManagerService";
John Spurlockf4f6b4c2012-08-25 12:08:03 -040071
72 private final Object mLock = new Object();
Jeff Brown62c82e42012-09-26 01:30:41 -070073
John Spurlockf4f6b4c2012-08-25 12:08:03 -040074 private final Context mContext;
Jeff Brown62c82e42012-09-26 01:30:41 -070075 private final DreamHandler mHandler;
76 private final DreamController mController;
77 private final PowerManager mPowerManager;
Jeff Brown970d4132014-07-19 11:33:47 -070078 private final PowerManagerInternal mPowerManagerInternal;
Jeff Brown26875502014-01-30 21:47:47 -080079 private final PowerManager.WakeLock mDozeWakeLock;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040080
Jeff Brown62c82e42012-09-26 01:30:41 -070081 private Binder mCurrentDreamToken;
82 private ComponentName mCurrentDreamName;
83 private int mCurrentDreamUserId;
84 private boolean mCurrentDreamIsTest;
Jeff Brown26875502014-01-30 21:47:47 -080085 private boolean mCurrentDreamCanDoze;
86 private boolean mCurrentDreamIsDozing;
Jeff Brownf6d46682014-07-17 22:44:20 -070087 private boolean mCurrentDreamIsWaking;
Jeff Brown970d4132014-07-19 11:33:47 -070088 private int mCurrentDreamDozeScreenState = Display.STATE_UNKNOWN;
89 private int mCurrentDreamDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
John Spurlockf4f6b4c2012-08-25 12:08:03 -040090
Jeff Brown4ccb8232014-01-16 22:16:42 -080091 public DreamManagerService(Context context) {
Jeff Brown567f7ca2014-01-30 23:38:03 -080092 super(context);
John Spurlockf4f6b4c2012-08-25 12:08:03 -040093 mContext = context;
Jeff Brown4ccb8232014-01-16 22:16:42 -080094 mHandler = new DreamHandler(FgThread.get().getLooper());
Jeff Brown62c82e42012-09-26 01:30:41 -070095 mController = new DreamController(context, mHandler, mControllerListener);
96
97 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
Jeff Brown970d4132014-07-19 11:33:47 -070098 mPowerManagerInternal = getLocalService(PowerManagerInternal.class);
Jeff Brown26875502014-01-30 21:47:47 -080099 mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, TAG);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400100 }
101
Jeff Brown567f7ca2014-01-30 23:38:03 -0800102 @Override
103 public void onStart() {
104 publishBinderService(DreamService.DREAM_SERVICE, new BinderService());
105 publishLocalService(DreamManagerInternal.class, new LocalService());
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400106 }
107
108 @Override
Jeff Brown567f7ca2014-01-30 23:38:03 -0800109 public void onBootPhase(int phase) {
110 if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
John Spurlockbf370992014-06-17 13:58:31 -0400111 if (Build.IS_DEBUGGABLE) {
112 SystemProperties.addChangeCallback(mSystemPropertiesChanged);
113 }
Jeff Brown567f7ca2014-01-30 23:38:03 -0800114 mContext.registerReceiver(new BroadcastReceiver() {
115 @Override
116 public void onReceive(Context context, Intent intent) {
Adrian Roos99182342016-06-15 15:30:46 -0700117 writePulseGestureEnabled();
Jeff Brown567f7ca2014-01-30 23:38:03 -0800118 synchronized (mLock) {
Jeff Brownf6d46682014-07-17 22:44:20 -0700119 stopDreamLocked(false /*immediate*/);
Jeff Brown567f7ca2014-01-30 23:38:03 -0800120 }
121 }
122 }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
Adrian Roos99182342016-06-15 15:30:46 -0700123 mContext.getContentResolver().registerContentObserver(
124 Settings.Secure.getUriFor(Settings.Secure.DOZE_ENABLED), false,
125 mDozeEnabledObserver, UserHandle.USER_ALL);
126 writePulseGestureEnabled();
John Spurlockda5b6f22013-08-14 09:46:52 -0400127 }
Jeff Brown567f7ca2014-01-30 23:38:03 -0800128 }
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400129
Jeff Brown567f7ca2014-01-30 23:38:03 -0800130 private void dumpInternal(PrintWriter pw) {
Jeff Brown62c82e42012-09-26 01:30:41 -0700131 pw.println("DREAM MANAGER (dumpsys dreams)");
132 pw.println();
Jeff Brown62c82e42012-09-26 01:30:41 -0700133 pw.println("mCurrentDreamToken=" + mCurrentDreamToken);
134 pw.println("mCurrentDreamName=" + mCurrentDreamName);
135 pw.println("mCurrentDreamUserId=" + mCurrentDreamUserId);
136 pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest);
Jeff Brown26875502014-01-30 21:47:47 -0800137 pw.println("mCurrentDreamCanDoze=" + mCurrentDreamCanDoze);
138 pw.println("mCurrentDreamIsDozing=" + mCurrentDreamIsDozing);
Jeff Brownf6d46682014-07-17 22:44:20 -0700139 pw.println("mCurrentDreamIsWaking=" + mCurrentDreamIsWaking);
Jeff Brown970d4132014-07-19 11:33:47 -0700140 pw.println("mCurrentDreamDozeScreenState="
141 + Display.stateToString(mCurrentDreamDozeScreenState));
142 pw.println("mCurrentDreamDozeScreenBrightness=" + mCurrentDreamDozeScreenBrightness);
John Spurlockbf370992014-06-17 13:58:31 -0400143 pw.println("getDozeComponent()=" + getDozeComponent());
Jeff Brown62c82e42012-09-26 01:30:41 -0700144 pw.println();
145
146 DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() {
147 @Override
Dianne Hackbornae6688b2015-02-11 17:02:41 -0800148 public void dump(PrintWriter pw, String prefix) {
Jeff Brown62c82e42012-09-26 01:30:41 -0700149 mController.dump(pw);
150 }
Dianne Hackbornae6688b2015-02-11 17:02:41 -0800151 }, pw, "", 200);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400152 }
153
Jeff Brown567f7ca2014-01-30 23:38:03 -0800154 private boolean isDreamingInternal() {
Jeff Brown62c82e42012-09-26 01:30:41 -0700155 synchronized (mLock) {
Jeff Brownf6d46682014-07-17 22:44:20 -0700156 return mCurrentDreamToken != null && !mCurrentDreamIsTest
157 && !mCurrentDreamIsWaking;
Jeff Brown62c82e42012-09-26 01:30:41 -0700158 }
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400159 }
160
Jeff Brown567f7ca2014-01-30 23:38:03 -0800161 private void requestDreamInternal() {
162 // Ask the power manager to nap. It will eventually call back into
163 // startDream() if/when it is appropriate to start dreaming.
164 // Because napping could cause the screen to turn off immediately if the dream
165 // cannot be started, we keep one eye open and gently poke user activity.
166 long time = SystemClock.uptimeMillis();
167 mPowerManager.userActivity(time, true /*noChangeLights*/);
168 mPowerManager.nap(time);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400169 }
170
Jeff Brown567f7ca2014-01-30 23:38:03 -0800171 private void requestAwakenInternal() {
172 // Treat an explicit request to awaken as user activity so that the
173 // device doesn't immediately go to sleep if the timeout expired,
174 // for example when being undocked.
175 long time = SystemClock.uptimeMillis();
176 mPowerManager.userActivity(time, false /*noChangeLights*/);
Jeff Brownf6d46682014-07-17 22:44:20 -0700177 stopDreamInternal(false /*immediate*/);
Jeff Brown567f7ca2014-01-30 23:38:03 -0800178 }
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400179
Jeff Brownf6d46682014-07-17 22:44:20 -0700180 private void finishSelfInternal(IBinder token, boolean immediate) {
Jeff Brown567f7ca2014-01-30 23:38:03 -0800181 if (DEBUG) {
Jeff Brownf6d46682014-07-17 22:44:20 -0700182 Slog.d(TAG, "Dream finished: " + token + ", immediate=" + immediate);
Jeff Brown62c82e42012-09-26 01:30:41 -0700183 }
184
Jeff Brown567f7ca2014-01-30 23:38:03 -0800185 // Note that a dream finishing and self-terminating is not
186 // itself considered user activity. If the dream is ending because
187 // the user interacted with the device then user activity will already
188 // have been poked so the device will stay awake a bit longer.
189 // If the dream is ending on its own for other reasons and no wake
190 // locks are held and the user activity timeout has expired then the
191 // device may simply go to sleep.
192 synchronized (mLock) {
193 if (mCurrentDreamToken == token) {
Jeff Brownf6d46682014-07-17 22:44:20 -0700194 stopDreamLocked(immediate);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400195 }
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400196 }
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400197 }
198
Jeff Brown567f7ca2014-01-30 23:38:03 -0800199 private void testDreamInternal(ComponentName dream, int userId) {
200 synchronized (mLock) {
Jeff Brown26875502014-01-30 21:47:47 -0800201 startDreamLocked(dream, true /*isTest*/, false /*canDoze*/, userId);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400202 }
203 }
204
Jeff Brown26875502014-01-30 21:47:47 -0800205 private void startDreamInternal(boolean doze) {
206 final int userId = ActivityManager.getCurrentUser();
John Spurlockeb8d1be2014-06-25 17:46:15 -0400207 final ComponentName dream = chooseDreamForUser(doze, userId);
Jeff Brown62c82e42012-09-26 01:30:41 -0700208 if (dream != null) {
209 synchronized (mLock) {
Jeff Brown26875502014-01-30 21:47:47 -0800210 startDreamLocked(dream, false /*isTest*/, doze, userId);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400211 }
212 }
Jeff Brown62c82e42012-09-26 01:30:41 -0700213 }
214
Jeff Brownf6d46682014-07-17 22:44:20 -0700215 private void stopDreamInternal(boolean immediate) {
Jeff Brown62c82e42012-09-26 01:30:41 -0700216 synchronized (mLock) {
Jeff Brownf6d46682014-07-17 22:44:20 -0700217 stopDreamLocked(immediate);
Jeff Brown62c82e42012-09-26 01:30:41 -0700218 }
219 }
220
Jeff Brown970d4132014-07-19 11:33:47 -0700221 private void startDozingInternal(IBinder token, int screenState,
222 int screenBrightness) {
Jeff Brown26875502014-01-30 21:47:47 -0800223 if (DEBUG) {
Jeff Brown970d4132014-07-19 11:33:47 -0700224 Slog.d(TAG, "Dream requested to start dozing: " + token
225 + ", screenState=" + screenState
226 + ", screenBrightness=" + screenBrightness);
Jeff Brown26875502014-01-30 21:47:47 -0800227 }
228
229 synchronized (mLock) {
Jeff Brown970d4132014-07-19 11:33:47 -0700230 if (mCurrentDreamToken == token && mCurrentDreamCanDoze) {
231 mCurrentDreamDozeScreenState = screenState;
232 mCurrentDreamDozeScreenBrightness = screenBrightness;
233 mPowerManagerInternal.setDozeOverrideFromDreamManager(
234 screenState, screenBrightness);
235 if (!mCurrentDreamIsDozing) {
236 mCurrentDreamIsDozing = true;
237 mDozeWakeLock.acquire();
238 }
Jeff Brown26875502014-01-30 21:47:47 -0800239 }
240 }
241 }
242
243 private void stopDozingInternal(IBinder token) {
244 if (DEBUG) {
245 Slog.d(TAG, "Dream requested to stop dozing: " + token);
246 }
247
248 synchronized (mLock) {
249 if (mCurrentDreamToken == token && mCurrentDreamIsDozing) {
250 mCurrentDreamIsDozing = false;
251 mDozeWakeLock.release();
Jeff Brown970d4132014-07-19 11:33:47 -0700252 mPowerManagerInternal.setDozeOverrideFromDreamManager(
253 Display.STATE_UNKNOWN, PowerManager.BRIGHTNESS_DEFAULT);
Jeff Brown26875502014-01-30 21:47:47 -0800254 }
255 }
256 }
257
John Spurlockeb8d1be2014-06-25 17:46:15 -0400258 private ComponentName chooseDreamForUser(boolean doze, int userId) {
259 if (doze) {
John Spurlocka4215ce2014-08-04 14:50:38 -0400260 ComponentName dozeComponent = getDozeComponent(userId);
John Spurlockeb8d1be2014-06-25 17:46:15 -0400261 return validateDream(dozeComponent) ? dozeComponent : null;
262 }
Jeff Brown62c82e42012-09-26 01:30:41 -0700263 ComponentName[] dreams = getDreamComponentsForUser(userId);
264 return dreams != null && dreams.length != 0 ? dreams[0] : null;
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400265 }
266
John Spurlockeb8d1be2014-06-25 17:46:15 -0400267 private boolean validateDream(ComponentName component) {
268 if (component == null) return false;
269 final ServiceInfo serviceInfo = getServiceInfo(component);
270 if (serviceInfo == null) {
271 Slog.w(TAG, "Dream " + component + " does not exist");
272 return false;
Dianne Hackborn955d8d62014-10-07 20:17:19 -0700273 } else if (serviceInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP
John Spurlockeb8d1be2014-06-25 17:46:15 -0400274 && !BIND_DREAM_SERVICE.equals(serviceInfo.permission)) {
275 Slog.w(TAG, "Dream " + component
276 + " is not available because its manifest is missing the " + BIND_DREAM_SERVICE
277 + " permission on the dream service declaration.");
278 return false;
279 }
280 return true;
281 }
282
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400283 private ComponentName[] getDreamComponentsForUser(int userId) {
284 String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Jeff Brown62c82e42012-09-26 01:30:41 -0700285 Settings.Secure.SCREENSAVER_COMPONENTS,
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400286 userId);
John Spurlockbbdb0622012-12-10 18:15:07 -0500287 ComponentName[] components = componentsFromString(names);
288
289 // first, ensure components point to valid services
290 List<ComponentName> validComponents = new ArrayList<ComponentName>();
291 if (components != null) {
292 for (ComponentName component : components) {
John Spurlockeb8d1be2014-06-25 17:46:15 -0400293 if (validateDream(component)) {
John Spurlockbbdb0622012-12-10 18:15:07 -0500294 validComponents.add(component);
John Spurlockbbdb0622012-12-10 18:15:07 -0500295 }
296 }
297 }
298
299 // fallback to the default dream component if necessary
300 if (validComponents.isEmpty()) {
Jeff Brown567f7ca2014-01-30 23:38:03 -0800301 ComponentName defaultDream = getDefaultDreamComponentForUser(userId);
John Spurlockbbdb0622012-12-10 18:15:07 -0500302 if (defaultDream != null) {
303 Slog.w(TAG, "Falling back to default dream " + defaultDream);
304 validComponents.add(defaultDream);
305 }
306 }
307 return validComponents.toArray(new ComponentName[validComponents.size()]);
308 }
309
Jeff Brown567f7ca2014-01-30 23:38:03 -0800310 private void setDreamComponentsForUser(int userId, ComponentName[] componentNames) {
311 Settings.Secure.putStringForUser(mContext.getContentResolver(),
312 Settings.Secure.SCREENSAVER_COMPONENTS,
313 componentsToString(componentNames),
314 userId);
315 }
316
317 private ComponentName getDefaultDreamComponentForUser(int userId) {
318 String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
319 Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
320 userId);
321 return name == null ? null : ComponentName.unflattenFromString(name);
322 }
323
Jeff Brown26875502014-01-30 21:47:47 -0800324 private ComponentName getDozeComponent() {
John Spurlocka4215ce2014-08-04 14:50:38 -0400325 return getDozeComponent(ActivityManager.getCurrentUser());
326 }
327
328 private ComponentName getDozeComponent(int userId) {
Jeff Brown26875502014-01-30 21:47:47 -0800329 // Read the component from a system property to facilitate debugging.
330 // Note that for production devices, the dream should actually be declared in
331 // a config.xml resource.
332 String name = Build.IS_DEBUGGABLE ? SystemProperties.get("debug.doze.component") : null;
333 if (TextUtils.isEmpty(name)) {
334 // Read the component from a config.xml resource.
335 // The value should be specified in a resource overlay for the product.
336 name = mContext.getResources().getString(
337 com.android.internal.R.string.config_dozeComponent);
338 }
John Spurlocka4215ce2014-08-04 14:50:38 -0400339 boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
340 Settings.Secure.DOZE_ENABLED, 1, userId) != 0;
341 return TextUtils.isEmpty(name) || !enabled ? null : ComponentName.unflattenFromString(name);
Jeff Brown26875502014-01-30 21:47:47 -0800342 }
343
John Spurlockeb8d1be2014-06-25 17:46:15 -0400344 private ServiceInfo getServiceInfo(ComponentName name) {
John Spurlockbbdb0622012-12-10 18:15:07 -0500345 try {
Jeff Sharkey60328372016-03-30 20:42:46 -0600346 return name != null ? mContext.getPackageManager().getServiceInfo(name,
347 PackageManager.MATCH_DEBUG_TRIAGED_MISSING) : null;
John Spurlockbbdb0622012-12-10 18:15:07 -0500348 } catch (NameNotFoundException e) {
John Spurlockeb8d1be2014-06-25 17:46:15 -0400349 return null;
John Spurlockbbdb0622012-12-10 18:15:07 -0500350 }
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400351 }
352
Jeff Brown62c82e42012-09-26 01:30:41 -0700353 private void startDreamLocked(final ComponentName name,
Jeff Brown26875502014-01-30 21:47:47 -0800354 final boolean isTest, final boolean canDoze, final int userId) {
Jeff Brown62c82e42012-09-26 01:30:41 -0700355 if (Objects.equal(mCurrentDreamName, name)
356 && mCurrentDreamIsTest == isTest
Jeff Brown26875502014-01-30 21:47:47 -0800357 && mCurrentDreamCanDoze == canDoze
Jeff Brown62c82e42012-09-26 01:30:41 -0700358 && mCurrentDreamUserId == userId) {
359 return;
360 }
361
Jeff Brownf6d46682014-07-17 22:44:20 -0700362 stopDreamLocked(true /*immediate*/);
Jeff Brown62c82e42012-09-26 01:30:41 -0700363
Jeff Brownf6d46682014-07-17 22:44:20 -0700364 Slog.i(TAG, "Entering dreamland.");
Jeff Brown62c82e42012-09-26 01:30:41 -0700365
366 final Binder newToken = new Binder();
367 mCurrentDreamToken = newToken;
368 mCurrentDreamName = name;
369 mCurrentDreamIsTest = isTest;
Jeff Brown26875502014-01-30 21:47:47 -0800370 mCurrentDreamCanDoze = canDoze;
Jeff Brown62c82e42012-09-26 01:30:41 -0700371 mCurrentDreamUserId = userId;
372
Adrian Roos7445c0b2016-09-06 16:45:46 -0700373 PowerManager.WakeLock wakeLock = mPowerManager
374 .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "startDream");
375 mHandler.post(wakeLock.wrap(
376 () -> mController.startDream(newToken, name, isTest, canDoze, userId, wakeLock)));
Jeff Brown62c82e42012-09-26 01:30:41 -0700377 }
378
Jeff Brownf6d46682014-07-17 22:44:20 -0700379 private void stopDreamLocked(final boolean immediate) {
Jeff Brown62c82e42012-09-26 01:30:41 -0700380 if (mCurrentDreamToken != null) {
Jeff Brownf6d46682014-07-17 22:44:20 -0700381 if (immediate) {
382 Slog.i(TAG, "Leaving dreamland.");
383 cleanupDreamLocked();
384 } else if (mCurrentDreamIsWaking) {
385 return; // already waking
386 } else {
387 Slog.i(TAG, "Gently waking up from dream.");
388 mCurrentDreamIsWaking = true;
389 }
Jeff Brown62c82e42012-09-26 01:30:41 -0700390
391 mHandler.post(new Runnable() {
392 @Override
393 public void run() {
Jeff Brownf6d46682014-07-17 22:44:20 -0700394 mController.stopDream(immediate);
Jeff Brown62c82e42012-09-26 01:30:41 -0700395 }
396 });
397 }
398 }
399
400 private void cleanupDreamLocked() {
401 mCurrentDreamToken = null;
402 mCurrentDreamName = null;
403 mCurrentDreamIsTest = false;
Jeff Brown26875502014-01-30 21:47:47 -0800404 mCurrentDreamCanDoze = false;
Jeff Brown62c82e42012-09-26 01:30:41 -0700405 mCurrentDreamUserId = 0;
Jeff Brownf6d46682014-07-17 22:44:20 -0700406 mCurrentDreamIsWaking = false;
Jeff Brown26875502014-01-30 21:47:47 -0800407 if (mCurrentDreamIsDozing) {
408 mCurrentDreamIsDozing = false;
409 mDozeWakeLock.release();
410 }
Jeff Brown970d4132014-07-19 11:33:47 -0700411 mCurrentDreamDozeScreenState = Display.STATE_UNKNOWN;
412 mCurrentDreamDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown62c82e42012-09-26 01:30:41 -0700413 }
414
415 private void checkPermission(String permission) {
416 if (mContext.checkCallingOrSelfPermission(permission)
417 != PackageManager.PERMISSION_GRANTED) {
418 throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
419 + ", must have permission " + permission);
420 }
421 }
422
Adrian Roos99182342016-06-15 15:30:46 -0700423 private void writePulseGestureEnabled() {
424 ComponentName name = getDozeComponent();
425 boolean dozeEnabled = validateDream(name);
426 LocalServices.getService(InputManagerInternal.class).setPulseGestureEnabled(dozeEnabled);
427 }
428
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400429 private static String componentsToString(ComponentName[] componentNames) {
430 StringBuilder names = new StringBuilder();
431 if (componentNames != null) {
432 for (ComponentName componentName : componentNames) {
433 if (names.length() > 0) {
434 names.append(',');
435 }
436 names.append(componentName.flattenToString());
437 }
438 }
439 return names.toString();
440 }
441
442 private static ComponentName[] componentsFromString(String names) {
John Spurlockf5df6892012-12-14 13:12:43 -0500443 if (names == null) {
444 return null;
445 }
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400446 String[] namesArray = names.split(",");
447 ComponentName[] componentNames = new ComponentName[namesArray.length];
448 for (int i = 0; i < namesArray.length; i++) {
449 componentNames[i] = ComponentName.unflattenFromString(namesArray[i]);
450 }
451 return componentNames;
452 }
453
Jeff Brown62c82e42012-09-26 01:30:41 -0700454 private final DreamController.Listener mControllerListener = new DreamController.Listener() {
455 @Override
456 public void onDreamStopped(Binder token) {
457 synchronized (mLock) {
458 if (mCurrentDreamToken == token) {
459 cleanupDreamLocked();
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400460 }
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400461 }
462 }
Jeff Brown62c82e42012-09-26 01:30:41 -0700463 };
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400464
Adrian Roos99182342016-06-15 15:30:46 -0700465 private final ContentObserver mDozeEnabledObserver = new ContentObserver(null) {
466 @Override
467 public void onChange(boolean selfChange) {
468 writePulseGestureEnabled();
469 }
470 };
471
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400472 /**
473 * Handler for asynchronous operations performed by the dream manager.
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400474 * Ensures operations to {@link DreamController} are single-threaded.
475 */
Jeff Brown62c82e42012-09-26 01:30:41 -0700476 private final class DreamHandler extends Handler {
477 public DreamHandler(Looper looper) {
478 super(looper, null, true /*async*/);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400479 }
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400480 }
Jeff Brown567f7ca2014-01-30 23:38:03 -0800481
482 private final class BinderService extends IDreamManager.Stub {
483 @Override // Binder call
484 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
485 if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
486 != PackageManager.PERMISSION_GRANTED) {
487 pw.println("Permission Denial: can't dump DreamManager from from pid="
488 + Binder.getCallingPid()
489 + ", uid=" + Binder.getCallingUid());
490 return;
491 }
492
493 final long ident = Binder.clearCallingIdentity();
494 try {
495 dumpInternal(pw);
496 } finally {
497 Binder.restoreCallingIdentity(ident);
498 }
499 }
500
501 @Override // Binder call
502 public ComponentName[] getDreamComponents() {
503 checkPermission(android.Manifest.permission.READ_DREAM_STATE);
504
505 final int userId = UserHandle.getCallingUserId();
506 final long ident = Binder.clearCallingIdentity();
507 try {
508 return getDreamComponentsForUser(userId);
509 } finally {
510 Binder.restoreCallingIdentity(ident);
511 }
512 }
513
514 @Override // Binder call
515 public void setDreamComponents(ComponentName[] componentNames) {
516 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
517
518 final int userId = UserHandle.getCallingUserId();
519 final long ident = Binder.clearCallingIdentity();
520 try {
521 setDreamComponentsForUser(userId, componentNames);
522 } finally {
523 Binder.restoreCallingIdentity(ident);
524 }
525 }
526
527 @Override // Binder call
528 public ComponentName getDefaultDreamComponent() {
529 checkPermission(android.Manifest.permission.READ_DREAM_STATE);
530
531 final int userId = UserHandle.getCallingUserId();
532 final long ident = Binder.clearCallingIdentity();
533 try {
534 return getDefaultDreamComponentForUser(userId);
535 } finally {
536 Binder.restoreCallingIdentity(ident);
537 }
538 }
539
540 @Override // Binder call
541 public boolean isDreaming() {
542 checkPermission(android.Manifest.permission.READ_DREAM_STATE);
543
544 final long ident = Binder.clearCallingIdentity();
545 try {
546 return isDreamingInternal();
547 } finally {
548 Binder.restoreCallingIdentity(ident);
549 }
550 }
551
552 @Override // Binder call
553 public void dream() {
554 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
555
556 final long ident = Binder.clearCallingIdentity();
557 try {
558 requestDreamInternal();
559 } finally {
560 Binder.restoreCallingIdentity(ident);
561 }
562 }
563
564 @Override // Binder call
565 public void testDream(ComponentName dream) {
566 if (dream == null) {
567 throw new IllegalArgumentException("dream must not be null");
568 }
569 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
570
571 final int callingUserId = UserHandle.getCallingUserId();
572 final int currentUserId = ActivityManager.getCurrentUser();
573 if (callingUserId != currentUserId) {
574 // This check is inherently prone to races but at least it's something.
575 Slog.w(TAG, "Aborted attempt to start a test dream while a different "
576 + " user is active: callingUserId=" + callingUserId
577 + ", currentUserId=" + currentUserId);
578 return;
579 }
580 final long ident = Binder.clearCallingIdentity();
581 try {
582 testDreamInternal(dream, callingUserId);
583 } finally {
584 Binder.restoreCallingIdentity(ident);
585 }
586 }
587
588 @Override // Binder call
589 public void awaken() {
590 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
591
592 final long ident = Binder.clearCallingIdentity();
593 try {
594 requestAwakenInternal();
595 } finally {
596 Binder.restoreCallingIdentity(ident);
597 }
598 }
599
600 @Override // Binder call
Jeff Brownf6d46682014-07-17 22:44:20 -0700601 public void finishSelf(IBinder token, boolean immediate) {
Jeff Brown567f7ca2014-01-30 23:38:03 -0800602 // Requires no permission, called by Dream from an arbitrary process.
603 if (token == null) {
604 throw new IllegalArgumentException("token must not be null");
605 }
606
607 final long ident = Binder.clearCallingIdentity();
608 try {
Jeff Brownf6d46682014-07-17 22:44:20 -0700609 finishSelfInternal(token, immediate);
Jeff Brown567f7ca2014-01-30 23:38:03 -0800610 } finally {
611 Binder.restoreCallingIdentity(ident);
612 }
613 }
Jeff Brown26875502014-01-30 21:47:47 -0800614
615 @Override // Binder call
Jeff Brown970d4132014-07-19 11:33:47 -0700616 public void startDozing(IBinder token, int screenState, int screenBrightness) {
Jeff Brown26875502014-01-30 21:47:47 -0800617 // Requires no permission, called by Dream from an arbitrary process.
618 if (token == null) {
619 throw new IllegalArgumentException("token must not be null");
620 }
621
622 final long ident = Binder.clearCallingIdentity();
623 try {
Jeff Brown970d4132014-07-19 11:33:47 -0700624 startDozingInternal(token, screenState, screenBrightness);
Jeff Brown26875502014-01-30 21:47:47 -0800625 } finally {
626 Binder.restoreCallingIdentity(ident);
627 }
628 }
629
630 @Override // Binder call
631 public void stopDozing(IBinder token) {
632 // Requires no permission, called by Dream from an arbitrary process.
633 if (token == null) {
634 throw new IllegalArgumentException("token must not be null");
635 }
636
637 final long ident = Binder.clearCallingIdentity();
638 try {
639 stopDozingInternal(token);
640 } finally {
641 Binder.restoreCallingIdentity(ident);
642 }
643 }
Jeff Brown567f7ca2014-01-30 23:38:03 -0800644 }
645
646 private final class LocalService extends DreamManagerInternal {
647 @Override
Jeff Brown26875502014-01-30 21:47:47 -0800648 public void startDream(boolean doze) {
649 startDreamInternal(doze);
Jeff Brown567f7ca2014-01-30 23:38:03 -0800650 }
651
652 @Override
Jeff Brownf6d46682014-07-17 22:44:20 -0700653 public void stopDream(boolean immediate) {
654 stopDreamInternal(immediate);
Jeff Brown567f7ca2014-01-30 23:38:03 -0800655 }
656
657 @Override
658 public boolean isDreaming() {
659 return isDreamingInternal();
660 }
661 }
Jeff Brown26875502014-01-30 21:47:47 -0800662
John Spurlockbf370992014-06-17 13:58:31 -0400663 private final Runnable mSystemPropertiesChanged = new Runnable() {
664 @Override
665 public void run() {
666 if (DEBUG) Slog.d(TAG, "System properties changed");
Jeff Brownf6d46682014-07-17 22:44:20 -0700667 synchronized (mLock) {
John Spurlockbf370992014-06-17 13:58:31 -0400668 if (mCurrentDreamName != null && mCurrentDreamCanDoze
669 && !mCurrentDreamName.equals(getDozeComponent())) {
Jeff Brownf6d46682014-07-17 22:44:20 -0700670 // May have updated the doze component, wake up
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700671 mPowerManager.wakeUp(SystemClock.uptimeMillis(),
672 "android.server.dreams:SYSPROP");
John Spurlockbf370992014-06-17 13:58:31 -0400673 }
674 }
675 }
676 };
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400677}