diff options
3 files changed, 152 insertions, 89 deletions
diff --git a/core/java/android/service/dreams/Sandman.java b/core/java/android/service/dreams/Sandman.java new file mode 100644 index 0000000..70142ce --- /dev/null +++ b/core/java/android/service/dreams/Sandman.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.dreams; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.PowerManager; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemClock; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.Slog; + +/** + * Internal helper for launching dreams to ensure consistency between the + * <code>UiModeManagerService</code> system service and the <code>Somnambulator</code> activity. + * + * @hide + */ +public final class Sandman { + private static final String TAG = "Sandman"; + + private static final int DEFAULT_SCREENSAVER_ENABLED = 1; + private static final int DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK = 1; + + // The component name of a special dock app that merely launches a dream. + // We don't want to launch this app when docked because it causes an unnecessary + // activity transition. We just want to start the dream. + private static final ComponentName SOMNAMBULATOR_COMPONENT = + new ComponentName("com.android.systemui", "com.android.systemui.Somnambulator"); + + + // The sandman is eternal. No one instantiates him. + private Sandman() { + } + + /** + * Returns true if the specified dock app intent should be started. + * False if we should dream instead, if appropriate. + */ + public static boolean shouldStartDockApp(Context context, Intent intent) { + ComponentName name = intent.resolveActivity(context.getPackageManager()); + return name != null && !name.equals(SOMNAMBULATOR_COMPONENT); + } + + /** + * Starts a dream manually. + */ + public static void startDreamByUserRequest(Context context) { + startDream(context, false); + } + + /** + * Starts a dream when docked if the system has been configured to do so, + * otherwise does nothing. + */ + public static void startDreamWhenDockedIfAppropriate(Context context) { + if (!isScreenSaverEnabled(context) + || !isScreenSaverActivatedOnDock(context)) { + Slog.i(TAG, "Dreams currently disabled for docks."); + return; + } + + startDream(context, true); + } + + private static void startDream(Context context, boolean docked) { + try { + IDreamManager dreamManagerService = IDreamManager.Stub.asInterface( + ServiceManager.getService(DreamService.DREAM_SERVICE)); + if (dreamManagerService != null && !dreamManagerService.isDreaming()) { + if (docked) { + Slog.i(TAG, "Activating dream while docked."); + + // Wake up. + // The power manager will wake up the system automatically when it starts + // receiving power from a dock but there is a race between that happening + // and the UI mode manager starting a dream. We want the system to already + // be awake by the time this happens. Otherwise the dream may not start. + PowerManager powerManager = + (PowerManager)context.getSystemService(Context.POWER_SERVICE); + powerManager.wakeUp(SystemClock.uptimeMillis()); + } else { + Slog.i(TAG, "Activating dream by user request."); + } + + // Dream. + dreamManagerService.dream(); + } + } catch (RemoteException ex) { + Slog.e(TAG, "Could not start dream when docked.", ex); + } + } + + private static boolean isScreenSaverEnabled(Context context) { + return Settings.Secure.getIntForUser(context.getContentResolver(), + Settings.Secure.SCREENSAVER_ENABLED, DEFAULT_SCREENSAVER_ENABLED, + UserHandle.USER_CURRENT) != 0; + } + + private static boolean isScreenSaverActivatedOnDock(Context context) { + return Settings.Secure.getIntForUser(context.getContentResolver(), + Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, + DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK, UserHandle.USER_CURRENT) != 0; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/Somnambulator.java b/packages/SystemUI/src/com/android/systemui/Somnambulator.java index 9356ff2..0dd6d92 100644 --- a/packages/SystemUI/src/com/android/systemui/Somnambulator.java +++ b/packages/SystemUI/src/com/android/systemui/Somnambulator.java @@ -1,4 +1,4 @@ -/*); +/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,38 +18,23 @@ package com.android.systemui; import android.app.Activity; import android.content.Intent; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.UserHandle; -import android.provider.Settings; -import android.service.dreams.DreamService; -import android.service.dreams.IDreamManager; -import android.util.Slog; - +import android.service.dreams.Sandman; + +/** + * A simple activity that launches a dream. + * <p> + * Note: This Activity is special. If this class is moved to another package or + * renamed, be sure to update the component name in {@link Sandman}. + * </p> + */ public class Somnambulator extends Activity { - public static final String TAG = "Somnambulator"; - - public static final int DEFAULT_SCREENSAVER_ENABLED = 1; - public static final int DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK = 1; - public Somnambulator() { } - private boolean isScreenSaverEnabled() { - return Settings.Secure.getIntForUser(getContentResolver(), - Settings.Secure.SCREENSAVER_ENABLED, DEFAULT_SCREENSAVER_ENABLED, - UserHandle.USER_CURRENT) != 0; - } - - private boolean isScreenSaverActivatedOnDock() { - return Settings.Secure.getIntForUser(getContentResolver(), - Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, - DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK, UserHandle.USER_CURRENT) != 0; - } - @Override public void onStart() { super.onStart(); + final Intent launchIntent = getIntent(); final String action = launchIntent.getAction(); if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) { @@ -64,23 +49,12 @@ public class Somnambulator extends Activity { setResult(RESULT_OK, resultIntent); } else { boolean docked = launchIntent.hasCategory(Intent.CATEGORY_DESK_DOCK); - - if (docked && !(isScreenSaverEnabled() && isScreenSaverActivatedOnDock())) { - Slog.i(TAG, "Dreams currently disabled for docks."); + if (docked) { + Sandman.startDreamWhenDockedIfAppropriate(this); } else { - IDreamManager somnambulist = IDreamManager.Stub.asInterface( - ServiceManager.checkService(DreamService.DREAM_SERVICE)); - if (somnambulist != null) { - try { - Slog.v(TAG, "Dreaming on " + (docked ? "dock insertion" : "user request")); - somnambulist.dream(); - } catch (RemoteException e) { - // fine, stay asleep then - } - } + Sandman.startDreamByUserRequest(this); } } finish(); } - } diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java index 2d4eb79..0e456f1 100644 --- a/services/java/com/android/server/UiModeManagerService.java +++ b/services/java/com/android/server/UiModeManagerService.java @@ -37,11 +37,9 @@ import android.os.Handler; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; -import android.service.dreams.DreamService; -import android.service.dreams.IDreamManager; +import android.service.dreams.Sandman; import android.util.Slog; import java.io.FileDescriptor; @@ -59,9 +57,6 @@ final class UiModeManagerService extends IUiModeManager.Stub { private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true; private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true; - private static final int DEFAULT_SCREENSAVER_ENABLED = 1; - private static final int DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK = 1; - private final Context mContext; private final TwilightService mTwilightService; private final Handler mHandler = new Handler(); @@ -496,18 +491,20 @@ final class UiModeManagerService extends IUiModeManager.Stub { // activity manager take care of both the start and config // change. Intent homeIntent = buildHomeIntent(category); - try { - int result = ActivityManagerNative.getDefault().startActivityWithConfig( - null, homeIntent, null, null, null, 0, 0, - mConfiguration, null, UserHandle.USER_CURRENT); - if (result >= ActivityManager.START_SUCCESS) { - dockAppStarted = true; - } else if (result != ActivityManager.START_INTENT_NOT_RESOLVED) { - Slog.e(TAG, "Could not start dock app: " + homeIntent - + ", startActivityWithConfig result " + result); + if (Sandman.shouldStartDockApp(mContext, homeIntent)) { + try { + int result = ActivityManagerNative.getDefault().startActivityWithConfig( + null, homeIntent, null, null, null, 0, 0, + mConfiguration, null, UserHandle.USER_CURRENT); + if (result >= ActivityManager.START_SUCCESS) { + dockAppStarted = true; + } else if (result != ActivityManager.START_INTENT_NOT_RESOLVED) { + Slog.e(TAG, "Could not start dock app: " + homeIntent + + ", startActivityWithConfig result " + result); + } + } catch (RemoteException ex) { + Slog.e(TAG, "Could not start dock app: " + homeIntent, ex); } - } catch (RemoteException ex) { - Slog.e(TAG, "Could not start dock app: " + homeIntent, ex); } } @@ -515,41 +512,11 @@ final class UiModeManagerService extends IUiModeManager.Stub { sendConfigurationLocked(); // If we did not start a dock app, then start dreaming if supported. - if (category != null && !dockAppStarted - && isScreenSaverEnabledLocked() && isScreenSaverActivatedOnDockLocked()) { - Slog.i(TAG, "Activating dream while docked."); - try { - IDreamManager dreamManagerService = IDreamManager.Stub.asInterface( - ServiceManager.getService(DreamService.DREAM_SERVICE)); - if (dreamManagerService != null && !dreamManagerService.isDreaming()) { - // Wake up. - // The power manager will wake up the system when it starts receiving power - // but there is a race between that happening and the UI mode manager - // starting a dream. We want the system to already be awake - // by the time this happens. Otherwise the dream may not start. - mPowerManager.wakeUp(SystemClock.uptimeMillis()); - - // Dream. - dreamManagerService.dream(); - } - } catch (RemoteException ex) { - Slog.e(TAG, "Could not start dream when docked.", ex); - } + if (category != null && !dockAppStarted) { + Sandman.startDreamWhenDockedIfAppropriate(mContext); } } - private boolean isScreenSaverEnabledLocked() { - return Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.SCREENSAVER_ENABLED, DEFAULT_SCREENSAVER_ENABLED, - UserHandle.USER_CURRENT) != 0; - } - - private boolean isScreenSaverActivatedOnDockLocked() { - return Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, - DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK, UserHandle.USER_CURRENT) != 0; - } - private void adjustStatusBarCarModeLocked() { if (mStatusBarManager == null) { mStatusBarManager = (StatusBarManager) |