111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown/* 211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * Copyright (C) 2012 The Android Open Source Project 311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * 411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * you may not use this file except in compliance with the License. 611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * You may obtain a copy of the License at 711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * 811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * 1011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * Unless required by applicable law or agreed to in writing, software 1111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * See the License for the specific language governing permissions and 1411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * limitations under the License. 1511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown */ 1611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 1711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownpackage android.service.dreams; 1811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 1911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.content.ComponentName; 2011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.content.Context; 2111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.content.Intent; 2211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.os.PowerManager; 2311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.os.RemoteException; 2411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.os.ServiceManager; 2511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.os.SystemClock; 2611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.os.UserHandle; 2711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.provider.Settings; 2811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.util.Slog; 2911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 3011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown/** 3111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * Internal helper for launching dreams to ensure consistency between the 3211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * <code>UiModeManagerService</code> system service and the <code>Somnambulator</code> activity. 3311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * 3411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * @hide 3511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown */ 3611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownpublic final class Sandman { 3711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown private static final String TAG = "Sandman"; 3811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 3911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // The component name of a special dock app that merely launches a dream. 4011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // We don't want to launch this app when docked because it causes an unnecessary 4111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // activity transition. We just want to start the dream. 4211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown private static final ComponentName SOMNAMBULATOR_COMPONENT = 4311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown new ComponentName("com.android.systemui", "com.android.systemui.Somnambulator"); 4411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 4511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 4611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // The sandman is eternal. No one instantiates him. 4711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown private Sandman() { 4811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 4911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 5011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown /** 5111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * Returns true if the specified dock app intent should be started. 5211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * False if we should dream instead, if appropriate. 5311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown */ 5411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown public static boolean shouldStartDockApp(Context context, Intent intent) { 5511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown ComponentName name = intent.resolveActivity(context.getPackageManager()); 5611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown return name != null && !name.equals(SOMNAMBULATOR_COMPONENT); 5711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 5811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 5911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown /** 6011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * Starts a dream manually. 6111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown */ 6211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown public static void startDreamByUserRequest(Context context) { 6311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown startDream(context, false); 6411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 6511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 6611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown /** 6711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * Starts a dream when docked if the system has been configured to do so, 6811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown * otherwise does nothing. 6911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown */ 7011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown public static void startDreamWhenDockedIfAppropriate(Context context) { 7111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown if (!isScreenSaverEnabled(context) 7211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown || !isScreenSaverActivatedOnDock(context)) { 7311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown Slog.i(TAG, "Dreams currently disabled for docks."); 7411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown return; 7511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 7611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 7711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown startDream(context, true); 7811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 7911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 8011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown private static void startDream(Context context, boolean docked) { 8111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown try { 8211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown IDreamManager dreamManagerService = IDreamManager.Stub.asInterface( 8311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown ServiceManager.getService(DreamService.DREAM_SERVICE)); 8411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown if (dreamManagerService != null && !dreamManagerService.isDreaming()) { 8511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown if (docked) { 8611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown Slog.i(TAG, "Activating dream while docked."); 8711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 8811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // Wake up. 8911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // The power manager will wake up the system automatically when it starts 9011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // receiving power from a dock but there is a race between that happening 9111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // and the UI mode manager starting a dream. We want the system to already 9211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // be awake by the time this happens. Otherwise the dream may not start. 9311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown PowerManager powerManager = 9411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown (PowerManager)context.getSystemService(Context.POWER_SERVICE); 9511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown powerManager.wakeUp(SystemClock.uptimeMillis()); 9611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } else { 9711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown Slog.i(TAG, "Activating dream by user request."); 9811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 9911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 10011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown // Dream. 10111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown dreamManagerService.dream(); 10211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 10311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } catch (RemoteException ex) { 10411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown Slog.e(TAG, "Could not start dream when docked.", ex); 10511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 10611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 10711159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 10811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown private static boolean isScreenSaverEnabled(Context context) { 109ed108f3d125b0a4cc465057e3514caf781cdea19John Spurlock int def = context.getResources().getBoolean( 110ed108f3d125b0a4cc465057e3514caf781cdea19John Spurlock com.android.internal.R.bool.config_dreamsEnabledByDefault) ? 1 : 0; 11111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown return Settings.Secure.getIntForUser(context.getContentResolver(), 112ed108f3d125b0a4cc465057e3514caf781cdea19John Spurlock Settings.Secure.SCREENSAVER_ENABLED, def, 11311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown UserHandle.USER_CURRENT) != 0; 11411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 11511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown 11611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown private static boolean isScreenSaverActivatedOnDock(Context context) { 117ed108f3d125b0a4cc465057e3514caf781cdea19John Spurlock int def = context.getResources().getBoolean( 118ed108f3d125b0a4cc465057e3514caf781cdea19John Spurlock com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault) ? 1 : 0; 11911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown return Settings.Secure.getIntForUser(context.getContentResolver(), 120ed108f3d125b0a4cc465057e3514caf781cdea19John Spurlock Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, def, 121ed108f3d125b0a4cc465057e3514caf781cdea19John Spurlock UserHandle.USER_CURRENT) != 0; 12211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown } 12311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown} 124