Merge "Add a new "doze mode" based on Dream components." into klp-modular-dev
This commit is contained in:
@ -176,6 +176,7 @@ LOCAL_SRC_FILES += \
|
|||||||
core/java/android/print/IWriteResultCallback.aidl \
|
core/java/android/print/IWriteResultCallback.aidl \
|
||||||
core/java/android/printservice/IPrintService.aidl \
|
core/java/android/printservice/IPrintService.aidl \
|
||||||
core/java/android/printservice/IPrintServiceClient.aidl \
|
core/java/android/printservice/IPrintServiceClient.aidl \
|
||||||
|
core/java/android/service/dreams/IDozeHardware.aidl \
|
||||||
core/java/android/service/dreams/IDreamManager.aidl \
|
core/java/android/service/dreams/IDreamManager.aidl \
|
||||||
core/java/android/service/dreams/IDreamService.aidl \
|
core/java/android/service/dreams/IDreamService.aidl \
|
||||||
core/java/android/service/wallpaper/IWallpaperConnection.aidl \
|
core/java/android/service/wallpaper/IWallpaperConnection.aidl \
|
||||||
|
@ -190,6 +190,18 @@ public final class PowerManager {
|
|||||||
*/
|
*/
|
||||||
public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 0x00000020;
|
public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 0x00000020;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wake lock level: Put the screen in a low power state and allow the CPU to suspend
|
||||||
|
* if no other wake locks are held.
|
||||||
|
* <p>
|
||||||
|
* This is used by the dream manager to implement doze mode. It currently
|
||||||
|
* has no effect unless the power manager is in the dozing state.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
public static final int DOZE_WAKE_LOCK = 0x00000040;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mask for the wake lock level component of a combined wake lock level and flags integer.
|
* Mask for the wake lock level component of a combined wake lock level and flags integer.
|
||||||
*
|
*
|
||||||
@ -418,6 +430,7 @@ public final class PowerManager {
|
|||||||
case SCREEN_BRIGHT_WAKE_LOCK:
|
case SCREEN_BRIGHT_WAKE_LOCK:
|
||||||
case FULL_WAKE_LOCK:
|
case FULL_WAKE_LOCK:
|
||||||
case PROXIMITY_SCREEN_OFF_WAKE_LOCK:
|
case PROXIMITY_SCREEN_OFF_WAKE_LOCK:
|
||||||
|
case DOZE_WAKE_LOCK:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Must specify a valid wake lock level.");
|
throw new IllegalArgumentException("Must specify a valid wake lock level.");
|
||||||
|
77
core/java/android/service/dreams/DozeHardware.java
Normal file
77
core/java/android/service/dreams/DozeHardware.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (C) 2014 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.os.RemoteException;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to low-level hardware features that a dream may use to provide
|
||||||
|
* a richer user experience while dozing.
|
||||||
|
* <p>
|
||||||
|
* This class contains functions that should be called by the dream to configure
|
||||||
|
* hardware before starting to doze and allowing the application processor to suspend.
|
||||||
|
* For example, the dream may provide the hardware with enough information to render
|
||||||
|
* some content on its own without any further assistance from the application processor.
|
||||||
|
* </p><p>
|
||||||
|
* This object is obtained by calling {@link DreamService#getDozeHardware()}.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @hide experimental
|
||||||
|
*/
|
||||||
|
public final class DozeHardware {
|
||||||
|
private static final String TAG = "DozeHardware";
|
||||||
|
|
||||||
|
public static final String MSG_ENABLE_MCU = "enable_mcu";
|
||||||
|
|
||||||
|
public static final byte[] VALUE_ON = "on".getBytes();
|
||||||
|
public static final byte[] VALUE_OFF = "off".getBytes();
|
||||||
|
|
||||||
|
private final IDozeHardware mHardware;
|
||||||
|
|
||||||
|
DozeHardware(IDozeHardware hardware) {
|
||||||
|
mHardware = hardware;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether to enable the microcontroller.
|
||||||
|
*
|
||||||
|
* @param enable If true, enables the MCU otherwise disables it.
|
||||||
|
*/
|
||||||
|
public void setEnableMcu(boolean enable) {
|
||||||
|
sendMessage(MSG_ENABLE_MCU, enable ? VALUE_ON : VALUE_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to the doze hardware module.
|
||||||
|
*
|
||||||
|
* @param msg The name of the message to send.
|
||||||
|
* @param arg An optional argument data blob, may be null.
|
||||||
|
* @return A result data blob, may be null.
|
||||||
|
*/
|
||||||
|
public byte[] sendMessage(String msg, byte[] arg) {
|
||||||
|
if (msg == null) {
|
||||||
|
throw new IllegalArgumentException("msg must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return mHardware.sendMessage(msg, arg);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
Log.e(TAG, "Failed to send message to doze hardware module.", ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,7 @@ public abstract class DreamManagerInternal {
|
|||||||
/**
|
/**
|
||||||
* Called by the power manager to start a dream.
|
* Called by the power manager to start a dream.
|
||||||
*/
|
*/
|
||||||
public abstract void startDream();
|
public abstract void startDream(boolean doze);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the power manager to stop a dream.
|
* Called by the power manager to stop a dream.
|
||||||
|
@ -20,12 +20,14 @@ import java.io.PrintWriter;
|
|||||||
|
|
||||||
import android.annotation.SdkConstant;
|
import android.annotation.SdkConstant;
|
||||||
import android.annotation.SdkConstant.SdkConstantType;
|
import android.annotation.SdkConstant.SdkConstantType;
|
||||||
|
import android.app.AlarmManager;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.view.ActionMode;
|
import android.view.ActionMode;
|
||||||
@ -42,6 +44,8 @@ import android.view.WindowManager.LayoutParams;
|
|||||||
import android.view.accessibility.AccessibilityEvent;
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
|
|
||||||
import com.android.internal.policy.PolicyManager;
|
import com.android.internal.policy.PolicyManager;
|
||||||
|
import com.android.internal.util.DumpUtils;
|
||||||
|
import com.android.internal.util.DumpUtils.Dump;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend this class to implement a custom dream (available to the user as a "Daydream").
|
* Extend this class to implement a custom dream (available to the user as a "Daydream").
|
||||||
@ -145,19 +149,26 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
*/
|
*/
|
||||||
public static final String DREAM_META_DATA = "android.service.dream";
|
public static final String DREAM_META_DATA = "android.service.dream";
|
||||||
|
|
||||||
|
private final IDreamManager mSandman;
|
||||||
private final Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
private IBinder mWindowToken;
|
private IBinder mWindowToken;
|
||||||
private Window mWindow;
|
private Window mWindow;
|
||||||
private WindowManager mWindowManager;
|
private WindowManager mWindowManager;
|
||||||
private IDreamManager mSandman;
|
|
||||||
private boolean mInteractive = false;
|
private boolean mInteractive = false;
|
||||||
private boolean mLowProfile = true;
|
private boolean mLowProfile = true;
|
||||||
private boolean mFullscreen = false;
|
private boolean mFullscreen = false;
|
||||||
private boolean mScreenBright = true;
|
private boolean mScreenBright = true;
|
||||||
private boolean mFinished;
|
private boolean mFinished;
|
||||||
|
private boolean mCanDoze;
|
||||||
|
private boolean mDozing;
|
||||||
|
private DozeHardware mDozeHardware;
|
||||||
|
|
||||||
private boolean mDebug = false;
|
private boolean mDebug = false;
|
||||||
|
|
||||||
|
public DreamService() {
|
||||||
|
mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@ -444,9 +455,11 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
* correct interactions with it (seeing when it is cleared etc).
|
* correct interactions with it (seeing when it is cleared etc).
|
||||||
*/
|
*/
|
||||||
public void setLowProfile(boolean lowProfile) {
|
public void setLowProfile(boolean lowProfile) {
|
||||||
mLowProfile = lowProfile;
|
if (mLowProfile != lowProfile) {
|
||||||
int flag = View.SYSTEM_UI_FLAG_LOW_PROFILE;
|
mLowProfile = lowProfile;
|
||||||
applySystemUiVisibilityFlags(mLowProfile ? flag : 0, flag);
|
int flag = View.SYSTEM_UI_FLAG_LOW_PROFILE;
|
||||||
|
applySystemUiVisibilityFlags(mLowProfile ? flag : 0, flag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -467,9 +480,11 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
* will be cleared.
|
* will be cleared.
|
||||||
*/
|
*/
|
||||||
public void setFullscreen(boolean fullscreen) {
|
public void setFullscreen(boolean fullscreen) {
|
||||||
mFullscreen = fullscreen;
|
if (mFullscreen != fullscreen) {
|
||||||
int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
mFullscreen = fullscreen;
|
||||||
applyWindowFlags(mFullscreen ? flag : 0, flag);
|
int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
||||||
|
applyWindowFlags(mFullscreen ? flag : 0, flag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -487,14 +502,16 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
* @param screenBright True to keep the screen bright while dreaming.
|
* @param screenBright True to keep the screen bright while dreaming.
|
||||||
*/
|
*/
|
||||||
public void setScreenBright(boolean screenBright) {
|
public void setScreenBright(boolean screenBright) {
|
||||||
mScreenBright = screenBright;
|
if (mScreenBright != screenBright) {
|
||||||
int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
mScreenBright = screenBright;
|
||||||
applyWindowFlags(mScreenBright ? flag : 0, flag);
|
int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||||
|
applyWindowFlags(mScreenBright ? flag : 0, flag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not this dream keeps the screen bright while dreaming. Defaults to false,
|
* Returns whether or not this dream keeps the screen bright while dreaming.
|
||||||
* allowing the screen to dim if necessary.
|
* Defaults to false, allowing the screen to dim if necessary.
|
||||||
*
|
*
|
||||||
* @see #setScreenBright(boolean)
|
* @see #setScreenBright(boolean)
|
||||||
*/
|
*/
|
||||||
@ -502,6 +519,119 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
return getWindowFlagValue(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, mScreenBright);
|
return getWindowFlagValue(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, mScreenBright);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this dream is allowed to doze.
|
||||||
|
* <p>
|
||||||
|
* The value returned by this method is only meaningful when the dream has started.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return True if this dream can doze.
|
||||||
|
* @see #startDozing
|
||||||
|
* @hide experimental
|
||||||
|
*/
|
||||||
|
public boolean canDoze() {
|
||||||
|
return mCanDoze;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts dozing, entering a deep dreamy sleep.
|
||||||
|
* <p>
|
||||||
|
* Dozing enables the system to conserve power while the user is not actively interacting
|
||||||
|
* with the device. While dozing, the display will remain on in a low-power state
|
||||||
|
* and will continue to show its previous contents but the application processor and
|
||||||
|
* other system components will be allowed to suspend when possible.
|
||||||
|
* </p><p>
|
||||||
|
* While the application processor is suspended, the dream may stop executing code
|
||||||
|
* for long periods of time. Prior to being suspended, the dream may schedule periodic
|
||||||
|
* wake-ups to render new content by scheduling an alarm with the {@link AlarmManager}.
|
||||||
|
* The dream may also keep the CPU awake by acquiring a
|
||||||
|
* {@link android.os.PowerManager#PARTIAL_WAKE_LOCK partial wake lock} when necessary.
|
||||||
|
* Note that since the purpose of doze mode is to conserve power (especially when
|
||||||
|
* running on battery), the dream should not wake the CPU very often or keep it
|
||||||
|
* awake for very long.
|
||||||
|
* </p><p>
|
||||||
|
* It is a good idea to call this method some time after the dream's entry animation
|
||||||
|
* has completed and the dream is ready to doze. It is important to completely
|
||||||
|
* finish all of the work needed before dozing since the application processor may
|
||||||
|
* be suspended at any moment once this method is called unless other wake locks
|
||||||
|
* are being held.
|
||||||
|
* </p><p>
|
||||||
|
* Call {@link #stopDozing} or {@link #finish} to stop dozing.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #stopDozing
|
||||||
|
* @hide experimental
|
||||||
|
*/
|
||||||
|
public void startDozing() {
|
||||||
|
if (mCanDoze && !mDozing) {
|
||||||
|
mDozing = true;
|
||||||
|
try {
|
||||||
|
mSandman.startDozing(mWindowToken);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
// system server died
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops dozing, returns to active dreaming.
|
||||||
|
* <p>
|
||||||
|
* This method reverses the effect of {@link #startDozing}. From this moment onward,
|
||||||
|
* the application processor will be kept awake as long as the dream is running
|
||||||
|
* or until the dream starts dozing again.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #startDozing
|
||||||
|
* @hide experimental
|
||||||
|
*/
|
||||||
|
public void stopDozing() {
|
||||||
|
if (mDozing) {
|
||||||
|
mDozing = false;
|
||||||
|
try {
|
||||||
|
mSandman.stopDozing(mWindowToken);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
// system server died
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the dream will allow the system to enter a low-power state while
|
||||||
|
* it is running without actually turning off the screen. Defaults to false,
|
||||||
|
* keeping the application processor awake while the dream is running.
|
||||||
|
*
|
||||||
|
* @return True if the dream is dozing.
|
||||||
|
*
|
||||||
|
* @see #setDozing(boolean)
|
||||||
|
* @hide experimental
|
||||||
|
*/
|
||||||
|
public boolean isDozing() {
|
||||||
|
return mDozing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an object that may be used to access low-level hardware features that a
|
||||||
|
* dream may use to provide a richer user experience while dozing.
|
||||||
|
*
|
||||||
|
* @return An instance of {@link DozeHardware} or null if this device does not offer
|
||||||
|
* hardware support for dozing.
|
||||||
|
*
|
||||||
|
* @hide experimental
|
||||||
|
*/
|
||||||
|
public DozeHardware getDozeHardware() {
|
||||||
|
if (mCanDoze && mDozeHardware == null) {
|
||||||
|
try {
|
||||||
|
IDozeHardware hardware = mSandman.getDozeHardware(mWindowToken);
|
||||||
|
if (hardware != null) {
|
||||||
|
mDozeHardware = new DozeHardware(hardware);
|
||||||
|
}
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
// system server died
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mDozeHardware;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when this Dream is constructed.
|
* Called when this Dream is constructed.
|
||||||
*/
|
*/
|
||||||
@ -536,7 +666,11 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the dream, detaches from the window, and wakes up.
|
* Stops the dream and detaches from the window.
|
||||||
|
* <p>
|
||||||
|
* When the dream ends, the system will be allowed to go to sleep fully unless there
|
||||||
|
* is a reason for it to be awake such as recent user activity or wake locks being held.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
public final void finish() {
|
public final void finish() {
|
||||||
if (mDebug) Slog.v(TAG, "finish()");
|
if (mDebug) Slog.v(TAG, "finish()");
|
||||||
@ -557,10 +691,6 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
|
|
||||||
// end public api
|
// end public api
|
||||||
|
|
||||||
private void loadSandman() {
|
|
||||||
mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by DreamController.stopDream() when the Dream is about to be unbound and destroyed.
|
* Called by DreamController.stopDream() when the Dream is about to be unbound and destroyed.
|
||||||
*
|
*
|
||||||
@ -572,23 +702,16 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (mDebug) Slog.v(TAG, "detach(): Calling onDreamingStopped()");
|
||||||
onDreamingStopped();
|
onDreamingStopped();
|
||||||
} catch (Throwable t) {
|
|
||||||
Slog.w(TAG, "Crashed in onDreamingStopped()", t);
|
|
||||||
// we were going to stop anyway
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mDebug) Slog.v(TAG, "detach(): Removing window from window manager");
|
if (mDebug) Slog.v(TAG, "detach(): Removing window from window manager");
|
||||||
try {
|
|
||||||
// force our window to be removed synchronously
|
// force our window to be removed synchronously
|
||||||
mWindowManager.removeViewImmediate(mWindow.getDecorView());
|
mWindowManager.removeViewImmediate(mWindow.getDecorView());
|
||||||
// the following will print a log message if it finds any other leaked windows
|
// the following will print a log message if it finds any other leaked windows
|
||||||
WindowManagerGlobal.getInstance().closeAll(mWindowToken,
|
WindowManagerGlobal.getInstance().closeAll(mWindowToken,
|
||||||
this.getClass().getName(), "Dream");
|
this.getClass().getName(), "Dream");
|
||||||
} catch (Throwable t) {
|
|
||||||
Slog.w(TAG, "Crashed removing window view", t);
|
|
||||||
}
|
|
||||||
|
|
||||||
mWindow = null;
|
mWindow = null;
|
||||||
mWindowToken = null;
|
mWindowToken = null;
|
||||||
@ -601,23 +724,30 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
*
|
*
|
||||||
* @param windowToken A window token that will allow a window to be created in the correct layer.
|
* @param windowToken A window token that will allow a window to be created in the correct layer.
|
||||||
*/
|
*/
|
||||||
private final void attach(IBinder windowToken) {
|
private final void attach(IBinder windowToken, boolean canDoze) {
|
||||||
if (mWindowToken != null) {
|
if (mWindowToken != null) {
|
||||||
Slog.e(TAG, "attach() called when already attached with token=" + mWindowToken);
|
Slog.e(TAG, "attach() called when already attached with token=" + mWindowToken);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mFinished) {
|
||||||
|
Slog.w(TAG, "attach() called after dream already finished");
|
||||||
|
try {
|
||||||
|
mSandman.finishSelf(windowToken);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
// system server died
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mDebug) Slog.v(TAG, "Attached on thread " + Thread.currentThread().getId());
|
if (mDebug) Slog.v(TAG, "Attached on thread " + Thread.currentThread().getId());
|
||||||
|
|
||||||
if (mSandman == null) {
|
|
||||||
loadSandman();
|
|
||||||
}
|
|
||||||
mWindowToken = windowToken;
|
mWindowToken = windowToken;
|
||||||
mWindow = PolicyManager.makeNewWindow(this);
|
mWindow = PolicyManager.makeNewWindow(this);
|
||||||
mWindow.setCallback(this);
|
mWindow.setCallback(this);
|
||||||
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
|
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
|
||||||
mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000));
|
mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000));
|
||||||
mWindow.setFormat(PixelFormat.OPAQUE);
|
mWindow.setFormat(PixelFormat.OPAQUE);
|
||||||
|
mCanDoze = canDoze;
|
||||||
|
|
||||||
if (mDebug) Slog.v(TAG, String.format("Attaching window token: %s to window of type %s",
|
if (mDebug) Slog.v(TAG, String.format("Attaching window token: %s to window of type %s",
|
||||||
windowToken, WindowManager.LayoutParams.TYPE_DREAM));
|
windowToken, WindowManager.LayoutParams.TYPE_DREAM));
|
||||||
@ -642,40 +772,25 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
mWindowManager = mWindow.getWindowManager();
|
mWindowManager = mWindow.getWindowManager();
|
||||||
|
|
||||||
if (mDebug) Slog.v(TAG, "Window added on thread " + Thread.currentThread().getId());
|
if (mDebug) Slog.v(TAG, "Window added on thread " + Thread.currentThread().getId());
|
||||||
try {
|
applySystemUiVisibilityFlags(
|
||||||
applySystemUiVisibilityFlags(
|
(mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0),
|
||||||
(mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0),
|
View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
||||||
View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes());
|
||||||
getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes());
|
|
||||||
} catch (Throwable t) {
|
|
||||||
Slog.w(TAG, "Crashed adding window view", t);
|
|
||||||
safelyFinish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// start it up
|
// start it up
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
if (mDebug) Slog.v(TAG, "Calling onDreamingStarted()");
|
||||||
onDreamingStarted();
|
onDreamingStarted();
|
||||||
} catch (Throwable t) {
|
|
||||||
Slog.w(TAG, "Crashed in onDreamingStarted()", t);
|
|
||||||
safelyFinish();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void safelyFinish() {
|
private void safelyFinish() {
|
||||||
if (mDebug) Slog.v(TAG, "safelyFinish()");
|
if (mDebug) Slog.v(TAG, "safelyFinish()");
|
||||||
try {
|
|
||||||
finish();
|
finish();
|
||||||
} catch (Throwable t) {
|
|
||||||
Slog.w(TAG, "Crashed in safelyFinish()", t);
|
|
||||||
finishInternal();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mFinished) {
|
if (!mFinished) {
|
||||||
Slog.w(TAG, "Bad dream, did not call super.finish()");
|
Slog.w(TAG, "Bad dream, did not call super.finish()");
|
||||||
@ -685,19 +800,21 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
|
|
||||||
private void finishInternal() {
|
private void finishInternal() {
|
||||||
if (mDebug) Slog.v(TAG, "finishInternal() mFinished = " + mFinished);
|
if (mDebug) Slog.v(TAG, "finishInternal() mFinished = " + mFinished);
|
||||||
if (mFinished) return;
|
|
||||||
try {
|
if (!mFinished) {
|
||||||
mFinished = true;
|
mFinished = true;
|
||||||
|
|
||||||
if (mSandman != null) {
|
if (mWindowToken == null) {
|
||||||
mSandman.finishSelf(mWindowToken);
|
Slog.w(TAG, "Finish was called before the dream was attached.");
|
||||||
} else {
|
} else {
|
||||||
Slog.w(TAG, "No dream manager found");
|
try {
|
||||||
|
mSandman.finishSelf(mWindowToken);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
// system server died
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stopSelf(); // if launched via any other means
|
|
||||||
|
|
||||||
} catch (Throwable t) {
|
stopSelf(); // if launched via any other means
|
||||||
Slog.w(TAG, "Crashed in finishInternal()", t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,32 +849,39 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||||
super.dump(fd, pw, args);
|
DumpUtils.dumpAsync(mHandler, new Dump() {
|
||||||
|
@Override
|
||||||
pw.print(TAG + ": ");
|
public void dump(PrintWriter pw) {
|
||||||
if (mWindowToken == null) {
|
pw.print(TAG + ": ");
|
||||||
pw.println("stopped");
|
if (mWindowToken == null) {
|
||||||
} else {
|
pw.println("stopped");
|
||||||
pw.println("running (token=" + mWindowToken + ")");
|
} else {
|
||||||
}
|
pw.println("running (token=" + mWindowToken + ")");
|
||||||
pw.println(" window: " + mWindow);
|
}
|
||||||
pw.print(" flags:");
|
pw.println(" window: " + mWindow);
|
||||||
if (isInteractive()) pw.print(" interactive");
|
pw.print(" flags:");
|
||||||
if (isLowProfile()) pw.print(" lowprofile");
|
if (isInteractive()) pw.print(" interactive");
|
||||||
if (isFullscreen()) pw.print(" fullscreen");
|
if (isLowProfile()) pw.print(" lowprofile");
|
||||||
if (isScreenBright()) pw.print(" bright");
|
if (isFullscreen()) pw.print(" fullscreen");
|
||||||
pw.println();
|
if (isScreenBright()) pw.print(" bright");
|
||||||
|
if (isDozing()) pw.print(" dozing");
|
||||||
|
pw.println();
|
||||||
|
}
|
||||||
|
}, pw, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DreamServiceWrapper extends IDreamService.Stub {
|
private final class DreamServiceWrapper extends IDreamService.Stub {
|
||||||
public void attach(final IBinder windowToken) {
|
@Override
|
||||||
|
public void attach(final IBinder windowToken, final boolean canDoze) {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
DreamService.this.attach(windowToken);
|
DreamService.this.attach(windowToken, canDoze);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void detach() {
|
public void detach() {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
24
core/java/android/service/dreams/IDozeHardware.aidl
Normal file
24
core/java/android/service/dreams/IDozeHardware.aidl
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
interface IDozeHardware {
|
||||||
|
byte[] sendMessage(String msg, in byte[] arg);
|
||||||
|
}
|
@ -16,10 +16,11 @@
|
|||||||
|
|
||||||
package android.service.dreams;
|
package android.service.dreams;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.service.dreams.IDozeHardware;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
interface IDreamManager {
|
interface IDreamManager {
|
||||||
@ -31,4 +32,7 @@ interface IDreamManager {
|
|||||||
void testDream(in ComponentName componentName);
|
void testDream(in ComponentName componentName);
|
||||||
boolean isDreaming();
|
boolean isDreaming();
|
||||||
void finishSelf(in IBinder token);
|
void finishSelf(in IBinder token);
|
||||||
|
void startDozing(in IBinder token);
|
||||||
|
void stopDozing(in IBinder token);
|
||||||
|
IDozeHardware getDozeHardware(in IBinder token);
|
||||||
}
|
}
|
@ -20,6 +20,6 @@ package android.service.dreams;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
oneway interface IDreamService {
|
oneway interface IDreamService {
|
||||||
void attach(IBinder windowToken);
|
void attach(IBinder windowToken, boolean canDoze);
|
||||||
void detach();
|
void detach();
|
||||||
}
|
}
|
||||||
|
@ -114,20 +114,6 @@ public interface WindowManagerPolicy {
|
|||||||
*/
|
*/
|
||||||
public final static int ACTION_PASS_TO_USER = 0x00000001;
|
public final static int ACTION_PASS_TO_USER = 0x00000001;
|
||||||
|
|
||||||
/**
|
|
||||||
* This key event should wake the device.
|
|
||||||
* To be returned from {@link #interceptKeyBeforeQueueing}.
|
|
||||||
* Do not return this and {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}.
|
|
||||||
*/
|
|
||||||
public final static int ACTION_WAKE_UP = 0x00000002;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This key event should put the device to sleep (and engage keyguard if necessary)
|
|
||||||
* To be returned from {@link #interceptKeyBeforeQueueing}.
|
|
||||||
* Do not return this and {@link #ACTION_WAKE_UP} or {@link #ACTION_PASS_TO_USER}.
|
|
||||||
*/
|
|
||||||
public final static int ACTION_GO_TO_SLEEP = 0x00000004;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to the Window Manager state associated with a particular
|
* Interface to the Window Manager state associated with a particular
|
||||||
* window. You can hold on to an instance of this interface from the call
|
* window. You can hold on to an instance of this interface from the call
|
||||||
@ -751,8 +737,7 @@ public interface WindowManagerPolicy {
|
|||||||
* @param policyFlags The policy flags associated with the key.
|
* @param policyFlags The policy flags associated with the key.
|
||||||
* @param isScreenOn True if the screen is already on
|
* @param isScreenOn True if the screen is already on
|
||||||
*
|
*
|
||||||
* @return The bitwise or of the {@link #ACTION_PASS_TO_USER},
|
* @return Actions flags: may be {@link #ACTION_PASS_TO_USER}.
|
||||||
* {@link #ACTION_WAKE_UP} and {@link #ACTION_GO_TO_SLEEP} flags.
|
|
||||||
*/
|
*/
|
||||||
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
|
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
|
||||||
|
|
||||||
@ -765,10 +750,9 @@ public interface WindowManagerPolicy {
|
|||||||
* because it's the most fragile.
|
* because it's the most fragile.
|
||||||
* @param policyFlags The policy flags associated with the motion.
|
* @param policyFlags The policy flags associated with the motion.
|
||||||
*
|
*
|
||||||
* @return The bitwise or of the {@link #ACTION_PASS_TO_USER},
|
* @return Actions flags: may be {@link #ACTION_PASS_TO_USER}.
|
||||||
* {@link #ACTION_WAKE_UP} and {@link #ACTION_GO_TO_SLEEP} flags.
|
|
||||||
*/
|
*/
|
||||||
public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags);
|
public int interceptMotionBeforeQueueingWhenScreenOff(long whenNanos, int policyFlags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the input dispatcher thread before a key is dispatched to a window.
|
* Called from the input dispatcher thread before a key is dispatched to a window.
|
||||||
|
@ -652,6 +652,11 @@
|
|||||||
Must be in the range specified by minimum and maximum. -->
|
Must be in the range specified by minimum and maximum. -->
|
||||||
<integer name="config_screenBrightnessSettingDefault">102</integer>
|
<integer name="config_screenBrightnessSettingDefault">102</integer>
|
||||||
|
|
||||||
|
<!-- Screen brightness used to dim the screen while dozing in a very low power state.
|
||||||
|
May be less than the minimum allowed brightness setting
|
||||||
|
that can be set by the user. -->
|
||||||
|
<integer name="config_screenBrightnessDoze">1</integer>
|
||||||
|
|
||||||
<!-- Screen brightness used to dim the screen when the user activity
|
<!-- Screen brightness used to dim the screen when the user activity
|
||||||
timeout expires. May be less than the minimum allowed brightness setting
|
timeout expires. May be less than the minimum allowed brightness setting
|
||||||
that can be set by the user. -->
|
that can be set by the user. -->
|
||||||
@ -1083,6 +1088,70 @@
|
|||||||
<!-- ComponentName of the default dream (Settings.Secure.SCREENSAVER_COMPONENT) -->
|
<!-- ComponentName of the default dream (Settings.Secure.SCREENSAVER_COMPONENT) -->
|
||||||
<string name="config_dreamsDefaultComponent">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
|
<string name="config_dreamsDefaultComponent">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
|
||||||
|
|
||||||
|
<!-- Are we allowed to dream while not plugged in? -->
|
||||||
|
<bool name="config_dreamsEnabledOnBattery">false</bool>
|
||||||
|
<!-- Minimum battery level to allow dreaming when powered.
|
||||||
|
Use -1 to disable this safety feature. -->
|
||||||
|
<integer name="config_dreamsBatteryLevelMinimumWhenPowered">-1</integer>
|
||||||
|
<!-- Minimum battery level to allow dreaming when not powered.
|
||||||
|
Use -1 to disable this safety feature. -->
|
||||||
|
<integer name="config_dreamsBatteryLevelMinimumWhenNotPowered">15</integer>
|
||||||
|
<!-- If the battery level drops by this percentage and the user activity timeout
|
||||||
|
has expired, then assume the device is receiving insufficient current to charge
|
||||||
|
effectively and terminate the dream. Use -1 to disable this safety feature. -->
|
||||||
|
<integer name="config_dreamsBatteryLevelDrainCutoff">5</integer>
|
||||||
|
|
||||||
|
<!-- ComponentName of a dream to show whenever the system would otherwise have
|
||||||
|
gone to sleep. When the PowerManager is asked to go to sleep, it will instead
|
||||||
|
try to start this dream if possible. The dream should typically call startDozing()
|
||||||
|
to put the display into a low power state and allow the application processor
|
||||||
|
to be suspended. When the dream ends, the system will go to sleep as usual.
|
||||||
|
Specify the component name (Settings.Secure.SCREENSAVER_COMPONENT) or an
|
||||||
|
empty string if none.
|
||||||
|
|
||||||
|
Note that doze dreams are not subject to the same start conditions as ordinary dreams.
|
||||||
|
Doze dreams will run whenever the power manager is in a dozing state. -->
|
||||||
|
<string name="config_dozeComponent"></string>
|
||||||
|
|
||||||
|
<!-- Power Management: Specifies whether to decouple the auto-suspend state of the
|
||||||
|
device from the display on/off state.
|
||||||
|
|
||||||
|
When false, autosuspend_disable() will be called before the display is turned on
|
||||||
|
and autosuspend_enable() will be called after the display is turned off.
|
||||||
|
This mode provides best compatibility for devices using legacy power management
|
||||||
|
features such as early suspend / late resume.
|
||||||
|
|
||||||
|
When true, autosuspend_display() and autosuspend_enable() will be called
|
||||||
|
independently of whether the display is being turned on or off. This mode
|
||||||
|
enables the power manager to suspend the application processor while the
|
||||||
|
display is on.
|
||||||
|
|
||||||
|
This resource should be set to "true" when a doze component has been specified
|
||||||
|
to maximize power savings but not all devices support it.
|
||||||
|
|
||||||
|
Refer to autosuspend.h for details.
|
||||||
|
-->
|
||||||
|
<bool name="config_powerDecoupleAutoSuspendModeFromDisplay">false</bool>
|
||||||
|
|
||||||
|
<!-- Power Management: Specifies whether to decouple the interactive state of the
|
||||||
|
device from the display on/off state.
|
||||||
|
|
||||||
|
When false, setInteractive(..., true) will be called before the display is turned on
|
||||||
|
and setInteractive(..., false) will be called after the display is turned off.
|
||||||
|
This mode provides best compatibility for devices that expect the interactive
|
||||||
|
state to be tied to the display state.
|
||||||
|
|
||||||
|
When true, setInteractive(...) will be called independently of whether the display
|
||||||
|
is being turned on or off. This mode enables the power manager to reduce
|
||||||
|
clocks and disable the touch controller while the display is on.
|
||||||
|
|
||||||
|
This resource should be set to "true" when a doze component has been specified
|
||||||
|
to maximize power savings but not all devices support it.
|
||||||
|
|
||||||
|
Refer to power.h for details.
|
||||||
|
-->
|
||||||
|
<bool name="config_powerDecoupleInteractiveModeFromDisplay">false</bool>
|
||||||
|
|
||||||
<!-- Base "touch slop" value used by ViewConfiguration as a
|
<!-- Base "touch slop" value used by ViewConfiguration as a
|
||||||
movement threshold where scrolling should begin. -->
|
movement threshold where scrolling should begin. -->
|
||||||
<dimen name="config_viewConfigurationTouchSlop">8dp</dimen>
|
<dimen name="config_viewConfigurationTouchSlop">8dp</dimen>
|
||||||
|
@ -1504,6 +1504,7 @@
|
|||||||
<java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
|
<java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
|
||||||
<java-symbol type="integer" name="config_screenBrightnessSettingDefault" />
|
<java-symbol type="integer" name="config_screenBrightnessSettingDefault" />
|
||||||
<java-symbol type="integer" name="config_screenBrightnessDim" />
|
<java-symbol type="integer" name="config_screenBrightnessDim" />
|
||||||
|
<java-symbol type="integer" name="config_screenBrightnessDoze" />
|
||||||
<java-symbol type="integer" name="config_shutdownBatteryTemperature" />
|
<java-symbol type="integer" name="config_shutdownBatteryTemperature" />
|
||||||
<java-symbol type="integer" name="config_undockedHdmiRotation" />
|
<java-symbol type="integer" name="config_undockedHdmiRotation" />
|
||||||
<java-symbol type="integer" name="config_virtualKeyQuietTimeMillis" />
|
<java-symbol type="integer" name="config_virtualKeyQuietTimeMillis" />
|
||||||
@ -1608,11 +1609,18 @@
|
|||||||
<java-symbol type="xml" name="storage_list" />
|
<java-symbol type="xml" name="storage_list" />
|
||||||
<java-symbol type="bool" name="config_dreamsSupported" />
|
<java-symbol type="bool" name="config_dreamsSupported" />
|
||||||
<java-symbol type="bool" name="config_dreamsEnabledByDefault" />
|
<java-symbol type="bool" name="config_dreamsEnabledByDefault" />
|
||||||
|
<java-symbol type="bool" name="config_dreamsEnabledOnBattery" />
|
||||||
<java-symbol type="bool" name="config_dreamsActivatedOnDockByDefault" />
|
<java-symbol type="bool" name="config_dreamsActivatedOnDockByDefault" />
|
||||||
<java-symbol type="bool" name="config_dreamsActivatedOnSleepByDefault" />
|
<java-symbol type="bool" name="config_dreamsActivatedOnSleepByDefault" />
|
||||||
|
<java-symbol type="integer" name="config_dreamsBatteryLevelMinimumWhenPowered" />
|
||||||
|
<java-symbol type="integer" name="config_dreamsBatteryLevelMinimumWhenNotPowered" />
|
||||||
|
<java-symbol type="integer" name="config_dreamsBatteryLevelDrainCutoff" />
|
||||||
<java-symbol type="string" name="config_dreamsDefaultComponent" />
|
<java-symbol type="string" name="config_dreamsDefaultComponent" />
|
||||||
|
<java-symbol type="string" name="config_dozeComponent" />
|
||||||
<java-symbol type="string" name="enable_explore_by_touch_warning_title" />
|
<java-symbol type="string" name="enable_explore_by_touch_warning_title" />
|
||||||
<java-symbol type="string" name="enable_explore_by_touch_warning_message" />
|
<java-symbol type="string" name="enable_explore_by_touch_warning_message" />
|
||||||
|
<java-symbol type="bool" name="config_powerDecoupleAutoSuspendModeFromDisplay" />
|
||||||
|
<java-symbol type="bool" name="config_powerDecoupleInteractiveModeFromDisplay" />
|
||||||
|
|
||||||
<java-symbol type="layout" name="resolver_list" />
|
<java-symbol type="layout" name="resolver_list" />
|
||||||
<java-symbol type="id" name="resolver_list" />
|
<java-symbol type="id" name="resolver_list" />
|
||||||
|
@ -3808,14 +3808,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
if (keyCode == KeyEvent.KEYCODE_POWER) {
|
if (keyCode == KeyEvent.KEYCODE_POWER) {
|
||||||
policyFlags |= WindowManagerPolicy.FLAG_WAKE;
|
policyFlags |= WindowManagerPolicy.FLAG_WAKE;
|
||||||
}
|
}
|
||||||
final boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
|
|
||||||
| WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
|
|
||||||
|
|
||||||
if (DEBUG_INPUT) {
|
if (DEBUG_INPUT) {
|
||||||
Log.d(TAG, "interceptKeyTq keycode=" + keyCode
|
Log.d(TAG, "interceptKeyTq keycode=" + keyCode
|
||||||
+ " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive
|
+ " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive
|
||||||
+ " policyFlags=" + Integer.toHexString(policyFlags)
|
+ " policyFlags=" + Integer.toHexString(policyFlags));
|
||||||
+ " isWakeKey=" + isWakeKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
|
if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
|
||||||
@ -3832,6 +3829,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
// the device some other way (which is why we have an exemption here for injected
|
// the device some other way (which is why we have an exemption here for injected
|
||||||
// events).
|
// events).
|
||||||
int result;
|
int result;
|
||||||
|
boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
|
||||||
|
| WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
|
||||||
if (isScreenOn || (isInjected && !isWakeKey)) {
|
if (isScreenOn || (isInjected && !isWakeKey)) {
|
||||||
// When the screen is on or if the key is injected pass the key to the application.
|
// When the screen is on or if the key is injected pass the key to the application.
|
||||||
result = ACTION_PASS_TO_USER;
|
result = ACTION_PASS_TO_USER;
|
||||||
@ -3839,8 +3838,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
// When the screen is off and the key is not injected, determine whether
|
// When the screen is off and the key is not injected, determine whether
|
||||||
// to wake the device but don't pass the key to the application.
|
// to wake the device but don't pass the key to the application.
|
||||||
result = 0;
|
result = 0;
|
||||||
if (down && isWakeKey && isWakeKeyWhenScreenOff(keyCode)) {
|
if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) {
|
||||||
result |= ACTION_WAKE_UP;
|
isWakeKey = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3950,7 +3949,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
}
|
}
|
||||||
if ((mEndcallBehavior
|
if ((mEndcallBehavior
|
||||||
& Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
|
& Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
|
||||||
result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
|
mPowerManager.goToSleep(event.getEventTime());
|
||||||
|
isWakeKey = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3994,7 +3994,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
mPowerKeyTriggered = false;
|
mPowerKeyTriggered = false;
|
||||||
cancelPendingScreenshotChordAction();
|
cancelPendingScreenshotChordAction();
|
||||||
if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
|
if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
|
||||||
result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
|
mPowerManager.goToSleep(event.getEventTime());
|
||||||
|
isWakeKey = false;
|
||||||
}
|
}
|
||||||
mPendingPowerKeyUpCanceled = false;
|
mPendingPowerKeyUpCanceled = false;
|
||||||
}
|
}
|
||||||
@ -4064,6 +4065,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isWakeKey) {
|
||||||
|
mPowerManager.wakeUp(event.getEventTime());
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4104,13 +4109,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
|
public int interceptMotionBeforeQueueingWhenScreenOff(long whenNanos, int policyFlags) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
final boolean isWakeMotion = (policyFlags
|
final boolean isWakeMotion = (policyFlags
|
||||||
& (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
|
& (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
|
||||||
if (isWakeMotion) {
|
if (isWakeMotion) {
|
||||||
result |= ACTION_WAKE_UP;
|
mPowerManager.wakeUp(whenNanos / 1000000);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,7 @@ final class DreamController {
|
|||||||
pw.println(" mToken=" + mCurrentDream.mToken);
|
pw.println(" mToken=" + mCurrentDream.mToken);
|
||||||
pw.println(" mName=" + mCurrentDream.mName);
|
pw.println(" mName=" + mCurrentDream.mName);
|
||||||
pw.println(" mIsTest=" + mCurrentDream.mIsTest);
|
pw.println(" mIsTest=" + mCurrentDream.mIsTest);
|
||||||
|
pw.println(" mCanDoze=" + mCurrentDream.mCanDoze);
|
||||||
pw.println(" mUserId=" + mCurrentDream.mUserId);
|
pw.println(" mUserId=" + mCurrentDream.mUserId);
|
||||||
pw.println(" mBound=" + mCurrentDream.mBound);
|
pw.println(" mBound=" + mCurrentDream.mBound);
|
||||||
pw.println(" mService=" + mCurrentDream.mService);
|
pw.println(" mService=" + mCurrentDream.mService);
|
||||||
@ -94,15 +95,18 @@ final class DreamController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startDream(Binder token, ComponentName name, boolean isTest, int userId) {
|
public void startDream(Binder token, ComponentName name,
|
||||||
|
boolean isTest, boolean canDoze, int userId) {
|
||||||
stopDream();
|
stopDream();
|
||||||
|
|
||||||
// Close the notification shade. Don't need to send to all, but better to be explicit.
|
// Close the notification shade. Don't need to send to all, but better to be explicit.
|
||||||
mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL);
|
mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL);
|
||||||
|
|
||||||
Slog.i(TAG, "Starting dream: name=" + name + ", isTest=" + isTest + ", userId=" + userId);
|
Slog.i(TAG, "Starting dream: name=" + name
|
||||||
|
+ ", isTest=" + isTest + ", canDoze=" + canDoze
|
||||||
|
+ ", userId=" + userId);
|
||||||
|
|
||||||
mCurrentDream = new DreamRecord(token, name, isTest, userId);
|
mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM);
|
mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM);
|
||||||
@ -140,7 +144,8 @@ final class DreamController {
|
|||||||
final DreamRecord oldDream = mCurrentDream;
|
final DreamRecord oldDream = mCurrentDream;
|
||||||
mCurrentDream = null;
|
mCurrentDream = null;
|
||||||
Slog.i(TAG, "Stopping dream: name=" + oldDream.mName
|
Slog.i(TAG, "Stopping dream: name=" + oldDream.mName
|
||||||
+ ", isTest=" + oldDream.mIsTest + ", userId=" + oldDream.mUserId);
|
+ ", isTest=" + oldDream.mIsTest + ", canDoze=" + oldDream.mCanDoze
|
||||||
|
+ ", userId=" + oldDream.mUserId);
|
||||||
|
|
||||||
mHandler.removeCallbacks(mStopUnconnectedDreamRunnable);
|
mHandler.removeCallbacks(mStopUnconnectedDreamRunnable);
|
||||||
|
|
||||||
@ -187,7 +192,7 @@ final class DreamController {
|
|||||||
private void attach(IDreamService service) {
|
private void attach(IDreamService service) {
|
||||||
try {
|
try {
|
||||||
service.asBinder().linkToDeath(mCurrentDream, 0);
|
service.asBinder().linkToDeath(mCurrentDream, 0);
|
||||||
service.attach(mCurrentDream.mToken);
|
service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze);
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Slog.e(TAG, "The dream service died unexpectedly.", ex);
|
Slog.e(TAG, "The dream service died unexpectedly.", ex);
|
||||||
stopDream();
|
stopDream();
|
||||||
@ -213,6 +218,7 @@ final class DreamController {
|
|||||||
public final Binder mToken;
|
public final Binder mToken;
|
||||||
public final ComponentName mName;
|
public final ComponentName mName;
|
||||||
public final boolean mIsTest;
|
public final boolean mIsTest;
|
||||||
|
public final boolean mCanDoze;
|
||||||
public final int mUserId;
|
public final int mUserId;
|
||||||
|
|
||||||
public boolean mBound;
|
public boolean mBound;
|
||||||
@ -221,10 +227,11 @@ final class DreamController {
|
|||||||
public boolean mSentStartBroadcast;
|
public boolean mSentStartBroadcast;
|
||||||
|
|
||||||
public DreamRecord(Binder token, ComponentName name,
|
public DreamRecord(Binder token, ComponentName name,
|
||||||
boolean isTest, int userId) {
|
boolean isTest, boolean canDoze, int userId) {
|
||||||
mToken = token;
|
mToken = token;
|
||||||
mName = name;
|
mName = name;
|
||||||
mIsTest = isTest;
|
mIsTest = isTest;
|
||||||
|
mCanDoze = canDoze;
|
||||||
mUserId = userId;
|
mUserId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,16 +30,20 @@ import android.content.IntentFilter;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.os.SystemProperties;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.service.dreams.DreamManagerInternal;
|
import android.service.dreams.DreamManagerInternal;
|
||||||
import android.service.dreams.DreamService;
|
import android.service.dreams.DreamService;
|
||||||
|
import android.service.dreams.IDozeHardware;
|
||||||
import android.service.dreams.IDreamManager;
|
import android.service.dreams.IDreamManager;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
@ -64,11 +68,16 @@ public final class DreamManagerService extends SystemService {
|
|||||||
private final DreamHandler mHandler;
|
private final DreamHandler mHandler;
|
||||||
private final DreamController mController;
|
private final DreamController mController;
|
||||||
private final PowerManager mPowerManager;
|
private final PowerManager mPowerManager;
|
||||||
|
private final PowerManager.WakeLock mDozeWakeLock;
|
||||||
|
private final McuHal mMcuHal; // synchronized on self
|
||||||
|
|
||||||
private Binder mCurrentDreamToken;
|
private Binder mCurrentDreamToken;
|
||||||
private ComponentName mCurrentDreamName;
|
private ComponentName mCurrentDreamName;
|
||||||
private int mCurrentDreamUserId;
|
private int mCurrentDreamUserId;
|
||||||
private boolean mCurrentDreamIsTest;
|
private boolean mCurrentDreamIsTest;
|
||||||
|
private boolean mCurrentDreamCanDoze;
|
||||||
|
private boolean mCurrentDreamIsDozing;
|
||||||
|
private DozeHardwareWrapper mCurrentDreamDozeHardware;
|
||||||
|
|
||||||
public DreamManagerService(Context context) {
|
public DreamManagerService(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -77,6 +86,12 @@ public final class DreamManagerService extends SystemService {
|
|||||||
mController = new DreamController(context, mHandler, mControllerListener);
|
mController = new DreamController(context, mHandler, mControllerListener);
|
||||||
|
|
||||||
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
|
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
|
||||||
|
mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, TAG);
|
||||||
|
|
||||||
|
mMcuHal = McuHal.open();
|
||||||
|
if (mMcuHal != null) {
|
||||||
|
mMcuHal.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -103,10 +118,15 @@ public final class DreamManagerService extends SystemService {
|
|||||||
pw.println("DREAM MANAGER (dumpsys dreams)");
|
pw.println("DREAM MANAGER (dumpsys dreams)");
|
||||||
pw.println();
|
pw.println();
|
||||||
|
|
||||||
|
pw.println("mMcuHal=" + mMcuHal);
|
||||||
|
pw.println();
|
||||||
pw.println("mCurrentDreamToken=" + mCurrentDreamToken);
|
pw.println("mCurrentDreamToken=" + mCurrentDreamToken);
|
||||||
pw.println("mCurrentDreamName=" + mCurrentDreamName);
|
pw.println("mCurrentDreamName=" + mCurrentDreamName);
|
||||||
pw.println("mCurrentDreamUserId=" + mCurrentDreamUserId);
|
pw.println("mCurrentDreamUserId=" + mCurrentDreamUserId);
|
||||||
pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest);
|
pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest);
|
||||||
|
pw.println("mCurrentDreamCanDoze=" + mCurrentDreamCanDoze);
|
||||||
|
pw.println("mCurrentDreamIsDozing=" + mCurrentDreamIsDozing);
|
||||||
|
pw.println("mCurrentDreamDozeHardware=" + mCurrentDreamDozeHardware);
|
||||||
pw.println();
|
pw.println();
|
||||||
|
|
||||||
DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() {
|
DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() {
|
||||||
@ -163,16 +183,16 @@ public final class DreamManagerService extends SystemService {
|
|||||||
|
|
||||||
private void testDreamInternal(ComponentName dream, int userId) {
|
private void testDreamInternal(ComponentName dream, int userId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
startDreamLocked(dream, true /*isTest*/, userId);
|
startDreamLocked(dream, true /*isTest*/, false /*canDoze*/, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startDreamInternal() {
|
private void startDreamInternal(boolean doze) {
|
||||||
int userId = ActivityManager.getCurrentUser();
|
final int userId = ActivityManager.getCurrentUser();
|
||||||
ComponentName dream = chooseDreamForUser(userId);
|
final ComponentName dream = doze ? getDozeComponent() : chooseDreamForUser(userId);
|
||||||
if (dream != null) {
|
if (dream != null) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
startDreamLocked(dream, false /*isTest*/, userId);
|
startDreamLocked(dream, false /*isTest*/, doze, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,6 +203,44 @@ public final class DreamManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startDozingInternal(IBinder token) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.d(TAG, "Dream requested to start dozing: " + token);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (mCurrentDreamToken == token && mCurrentDreamCanDoze
|
||||||
|
&& !mCurrentDreamIsDozing) {
|
||||||
|
mCurrentDreamIsDozing = true;
|
||||||
|
mDozeWakeLock.acquire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopDozingInternal(IBinder token) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.d(TAG, "Dream requested to stop dozing: " + token);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (mCurrentDreamToken == token && mCurrentDreamIsDozing) {
|
||||||
|
mCurrentDreamIsDozing = false;
|
||||||
|
mDozeWakeLock.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IDozeHardware getDozeHardwareInternal(IBinder token) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (mCurrentDreamToken == token && mCurrentDreamCanDoze
|
||||||
|
&& mCurrentDreamDozeHardware == null && mMcuHal != null) {
|
||||||
|
mCurrentDreamDozeHardware = new DozeHardwareWrapper();
|
||||||
|
return mCurrentDreamDozeHardware;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ComponentName chooseDreamForUser(int userId) {
|
private ComponentName chooseDreamForUser(int userId) {
|
||||||
ComponentName[] dreams = getDreamComponentsForUser(userId);
|
ComponentName[] dreams = getDreamComponentsForUser(userId);
|
||||||
return dreams != null && dreams.length != 0 ? dreams[0] : null;
|
return dreams != null && dreams.length != 0 ? dreams[0] : null;
|
||||||
@ -231,6 +289,20 @@ public final class DreamManagerService extends SystemService {
|
|||||||
return name == null ? null : ComponentName.unflattenFromString(name);
|
return name == null ? null : ComponentName.unflattenFromString(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ComponentName getDozeComponent() {
|
||||||
|
// Read the component from a system property to facilitate debugging.
|
||||||
|
// Note that for production devices, the dream should actually be declared in
|
||||||
|
// a config.xml resource.
|
||||||
|
String name = Build.IS_DEBUGGABLE ? SystemProperties.get("debug.doze.component") : null;
|
||||||
|
if (TextUtils.isEmpty(name)) {
|
||||||
|
// Read the component from a config.xml resource.
|
||||||
|
// The value should be specified in a resource overlay for the product.
|
||||||
|
name = mContext.getResources().getString(
|
||||||
|
com.android.internal.R.string.config_dozeComponent);
|
||||||
|
}
|
||||||
|
return TextUtils.isEmpty(name) ? null : ComponentName.unflattenFromString(name);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean serviceExists(ComponentName name) {
|
private boolean serviceExists(ComponentName name) {
|
||||||
try {
|
try {
|
||||||
return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null;
|
return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null;
|
||||||
@ -240,9 +312,10 @@ public final class DreamManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startDreamLocked(final ComponentName name,
|
private void startDreamLocked(final ComponentName name,
|
||||||
final boolean isTest, final int userId) {
|
final boolean isTest, final boolean canDoze, final int userId) {
|
||||||
if (Objects.equal(mCurrentDreamName, name)
|
if (Objects.equal(mCurrentDreamName, name)
|
||||||
&& mCurrentDreamIsTest == isTest
|
&& mCurrentDreamIsTest == isTest
|
||||||
|
&& mCurrentDreamCanDoze == canDoze
|
||||||
&& mCurrentDreamUserId == userId) {
|
&& mCurrentDreamUserId == userId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -255,12 +328,13 @@ public final class DreamManagerService extends SystemService {
|
|||||||
mCurrentDreamToken = newToken;
|
mCurrentDreamToken = newToken;
|
||||||
mCurrentDreamName = name;
|
mCurrentDreamName = name;
|
||||||
mCurrentDreamIsTest = isTest;
|
mCurrentDreamIsTest = isTest;
|
||||||
|
mCurrentDreamCanDoze = canDoze;
|
||||||
mCurrentDreamUserId = userId;
|
mCurrentDreamUserId = userId;
|
||||||
|
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mController.startDream(newToken, name, isTest, userId);
|
mController.startDream(newToken, name, isTest, canDoze, userId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -284,7 +358,16 @@ public final class DreamManagerService extends SystemService {
|
|||||||
mCurrentDreamToken = null;
|
mCurrentDreamToken = null;
|
||||||
mCurrentDreamName = null;
|
mCurrentDreamName = null;
|
||||||
mCurrentDreamIsTest = false;
|
mCurrentDreamIsTest = false;
|
||||||
|
mCurrentDreamCanDoze = false;
|
||||||
mCurrentDreamUserId = 0;
|
mCurrentDreamUserId = 0;
|
||||||
|
if (mCurrentDreamIsDozing) {
|
||||||
|
mCurrentDreamIsDozing = false;
|
||||||
|
mDozeWakeLock.release();
|
||||||
|
}
|
||||||
|
if (mCurrentDreamDozeHardware != null) {
|
||||||
|
mCurrentDreamDozeHardware.release();
|
||||||
|
mCurrentDreamDozeHardware = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkPermission(String permission) {
|
private void checkPermission(String permission) {
|
||||||
@ -473,12 +556,57 @@ public final class DreamManagerService extends SystemService {
|
|||||||
Binder.restoreCallingIdentity(ident);
|
Binder.restoreCallingIdentity(ident);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // Binder call
|
||||||
|
public void startDozing(IBinder token) {
|
||||||
|
// Requires no permission, called by Dream from an arbitrary process.
|
||||||
|
if (token == null) {
|
||||||
|
throw new IllegalArgumentException("token must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
final long ident = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
startDozingInternal(token);
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // Binder call
|
||||||
|
public void stopDozing(IBinder token) {
|
||||||
|
// Requires no permission, called by Dream from an arbitrary process.
|
||||||
|
if (token == null) {
|
||||||
|
throw new IllegalArgumentException("token must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
final long ident = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
stopDozingInternal(token);
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // Binder call
|
||||||
|
public IDozeHardware getDozeHardware(IBinder token) {
|
||||||
|
// Requires no permission, called by Dream from an arbitrary process.
|
||||||
|
if (token == null) {
|
||||||
|
throw new IllegalArgumentException("token must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
final long ident = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
return getDozeHardwareInternal(token);
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class LocalService extends DreamManagerInternal {
|
private final class LocalService extends DreamManagerInternal {
|
||||||
@Override
|
@Override
|
||||||
public void startDream() {
|
public void startDream(boolean doze) {
|
||||||
startDreamInternal();
|
startDreamInternal(doze);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -491,4 +619,37 @@ public final class DreamManagerService extends SystemService {
|
|||||||
return isDreamingInternal();
|
return isDreamingInternal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class DozeHardwareWrapper extends IDozeHardware.Stub {
|
||||||
|
private boolean mReleased;
|
||||||
|
|
||||||
|
public void release() {
|
||||||
|
synchronized (mMcuHal) {
|
||||||
|
if (!mReleased) {
|
||||||
|
mReleased = true;
|
||||||
|
mMcuHal.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // Binder call
|
||||||
|
public byte[] sendMessage(String msg, byte[] arg) {
|
||||||
|
if (msg == null) {
|
||||||
|
throw new IllegalArgumentException("msg must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
final long ident = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
synchronized (mMcuHal) {
|
||||||
|
if (mReleased) {
|
||||||
|
throw new IllegalStateException("This operation cannot be performed "
|
||||||
|
+ "because the dream has ended.");
|
||||||
|
}
|
||||||
|
return mMcuHal.sendMessage(msg, arg);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
46
services/core/java/com/android/server/dreams/McuHal.java
Normal file
46
services/core/java/com/android/server/dreams/McuHal.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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 com.android.server.dreams;
|
||||||
|
|
||||||
|
import android.service.dreams.DozeHardware;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to the low-level microcontroller hardware abstraction layer.
|
||||||
|
*/
|
||||||
|
final class McuHal {
|
||||||
|
private final long mPtr;
|
||||||
|
|
||||||
|
private static native long nativeOpen();
|
||||||
|
private static native byte[] nativeSendMessage(long ptr, String msg, byte[] arg);
|
||||||
|
|
||||||
|
private McuHal(long ptr) {
|
||||||
|
mPtr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static McuHal open() {
|
||||||
|
long ptr = nativeOpen();
|
||||||
|
return ptr != 0 ? new McuHal(ptr) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
sendMessage(DozeHardware.MSG_ENABLE_MCU, DozeHardware.VALUE_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] sendMessage(String msg, byte[] arg) {
|
||||||
|
return nativeSendMessage(mPtr, msg, arg);
|
||||||
|
}
|
||||||
|
}
|
@ -1329,8 +1329,9 @@ public class InputManagerService extends IInputManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Native callback.
|
// Native callback.
|
||||||
private int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
|
private int interceptMotionBeforeQueueingWhenScreenOff(long whenNanos, int policyFlags) {
|
||||||
return mWindowManagerCallbacks.interceptMotionBeforeQueueingWhenScreenOff(policyFlags);
|
return mWindowManagerCallbacks.interceptMotionBeforeQueueingWhenScreenOff(
|
||||||
|
whenNanos, policyFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Native callback.
|
// Native callback.
|
||||||
@ -1491,7 +1492,7 @@ public class InputManagerService extends IInputManager.Stub
|
|||||||
|
|
||||||
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
|
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
|
||||||
|
|
||||||
public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags);
|
public int interceptMotionBeforeQueueingWhenScreenOff(long whenNanos, int policyFlags);
|
||||||
|
|
||||||
public long interceptKeyBeforeDispatching(InputWindowHandle focus,
|
public long interceptKeyBeforeDispatching(InputWindowHandle focus,
|
||||||
KeyEvent event, int policyFlags);
|
KeyEvent event, int policyFlags);
|
||||||
|
@ -193,6 +193,9 @@ final class DisplayPowerController {
|
|||||||
// The light sensor, or null if not available or needed.
|
// The light sensor, or null if not available or needed.
|
||||||
private Sensor mLightSensor;
|
private Sensor mLightSensor;
|
||||||
|
|
||||||
|
// The doze screen brightness.
|
||||||
|
private final int mScreenBrightnessDozeConfig;
|
||||||
|
|
||||||
// The dim screen brightness.
|
// The dim screen brightness.
|
||||||
private final int mScreenBrightnessDimConfig;
|
private final int mScreenBrightnessDimConfig;
|
||||||
|
|
||||||
@ -364,6 +367,9 @@ final class DisplayPowerController {
|
|||||||
|
|
||||||
final Resources resources = context.getResources();
|
final Resources resources = context.getResources();
|
||||||
|
|
||||||
|
mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
|
||||||
|
com.android.internal.R.integer.config_screenBrightnessDoze));
|
||||||
|
|
||||||
mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
|
mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
|
||||||
com.android.internal.R.integer.config_screenBrightnessDim));
|
com.android.internal.R.integer.config_screenBrightnessDim));
|
||||||
|
|
||||||
@ -559,7 +565,7 @@ final class DisplayPowerController {
|
|||||||
final boolean mustNotify;
|
final boolean mustNotify;
|
||||||
boolean mustInitialize = false;
|
boolean mustInitialize = false;
|
||||||
boolean updateAutoBrightness = mTwilightChanged;
|
boolean updateAutoBrightness = mTwilightChanged;
|
||||||
boolean wasDim = false;
|
boolean wasDimOrDoze = false;
|
||||||
mTwilightChanged = false;
|
mTwilightChanged = false;
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
@ -579,7 +585,8 @@ final class DisplayPowerController {
|
|||||||
!= mPendingRequestLocked.screenAutoBrightnessAdjustment) {
|
!= mPendingRequestLocked.screenAutoBrightnessAdjustment) {
|
||||||
updateAutoBrightness = true;
|
updateAutoBrightness = true;
|
||||||
}
|
}
|
||||||
wasDim = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM);
|
wasDimOrDoze = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM
|
||||||
|
|| mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE);
|
||||||
mPowerRequest.copyFrom(mPendingRequestLocked);
|
mPowerRequest.copyFrom(mPendingRequestLocked);
|
||||||
mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
|
mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
|
||||||
mPendingWaitForNegativeProximityLocked = false;
|
mPendingWaitForNegativeProximityLocked = false;
|
||||||
@ -626,12 +633,12 @@ final class DisplayPowerController {
|
|||||||
|
|
||||||
// Turn on the light sensor if needed.
|
// Turn on the light sensor if needed.
|
||||||
if (mLightSensor != null) {
|
if (mLightSensor != null) {
|
||||||
setLightSensorEnabled(mPowerRequest.useAutoBrightness
|
setLightSensorEnabled(mPowerRequest.wantLightSensorEnabled(),
|
||||||
&& wantScreenOn(mPowerRequest.screenState), updateAutoBrightness);
|
updateAutoBrightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the screen brightness.
|
// Set the screen brightness.
|
||||||
if (wantScreenOn(mPowerRequest.screenState)) {
|
if (mPowerRequest.wantScreenOnAny()) {
|
||||||
int target;
|
int target;
|
||||||
boolean slow;
|
boolean slow;
|
||||||
if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) {
|
if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) {
|
||||||
@ -648,12 +655,16 @@ final class DisplayPowerController {
|
|||||||
slow = false;
|
slow = false;
|
||||||
mUsingScreenAutoBrightness = false;
|
mUsingScreenAutoBrightness = false;
|
||||||
}
|
}
|
||||||
if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {
|
if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) {
|
||||||
|
// Dim quickly to the doze state.
|
||||||
|
target = mScreenBrightnessDozeConfig;
|
||||||
|
slow = false;
|
||||||
|
} else if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {
|
||||||
// Dim quickly by at least some minimum amount.
|
// Dim quickly by at least some minimum amount.
|
||||||
target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION,
|
target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION,
|
||||||
mScreenBrightnessDimConfig);
|
mScreenBrightnessDimConfig);
|
||||||
slow = false;
|
slow = false;
|
||||||
} else if (wasDim) {
|
} else if (wasDimOrDoze) {
|
||||||
// Brighten quickly.
|
// Brighten quickly.
|
||||||
slow = false;
|
slow = false;
|
||||||
}
|
}
|
||||||
@ -666,7 +677,7 @@ final class DisplayPowerController {
|
|||||||
|
|
||||||
// Animate the screen on or off.
|
// Animate the screen on or off.
|
||||||
if (!mScreenOffBecauseOfProximity) {
|
if (!mScreenOffBecauseOfProximity) {
|
||||||
if (wantScreenOn(mPowerRequest.screenState)) {
|
if (mPowerRequest.wantScreenOnAny()) {
|
||||||
// Want screen on.
|
// Want screen on.
|
||||||
// Wait for previous off animation to complete beforehand.
|
// Wait for previous off animation to complete beforehand.
|
||||||
// It is relatively short but if we cancel it and switch to the
|
// It is relatively short but if we cancel it and switch to the
|
||||||
@ -1211,6 +1222,7 @@ final class DisplayPowerController {
|
|||||||
|
|
||||||
pw.println();
|
pw.println();
|
||||||
pw.println("Display Controller Configuration:");
|
pw.println("Display Controller Configuration:");
|
||||||
|
pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
|
||||||
pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
|
pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
|
||||||
pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
|
pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
|
||||||
pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
|
pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
|
||||||
@ -1288,15 +1300,6 @@ final class DisplayPowerController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean wantScreenOn(int state) {
|
|
||||||
switch (state) {
|
|
||||||
case DisplayPowerRequest.SCREEN_STATE_BRIGHT:
|
|
||||||
case DisplayPowerRequest.SCREEN_STATE_DIM:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronous callbacks from the power controller to the power manager service.
|
* Asynchronous callbacks from the power controller to the power manager service.
|
||||||
*/
|
*/
|
||||||
|
@ -30,10 +30,11 @@ import android.os.PowerManager;
|
|||||||
*/
|
*/
|
||||||
final class DisplayPowerRequest {
|
final class DisplayPowerRequest {
|
||||||
public static final int SCREEN_STATE_OFF = 0;
|
public static final int SCREEN_STATE_OFF = 0;
|
||||||
public static final int SCREEN_STATE_DIM = 1;
|
public static final int SCREEN_STATE_DOZE = 1;
|
||||||
public static final int SCREEN_STATE_BRIGHT = 2;
|
public static final int SCREEN_STATE_DIM = 2;
|
||||||
|
public static final int SCREEN_STATE_BRIGHT = 3;
|
||||||
|
|
||||||
// The requested minimum screen power state: off, dim or bright.
|
// The requested minimum screen power state: off, doze, dim or bright.
|
||||||
public int screenState;
|
public int screenState;
|
||||||
|
|
||||||
// If true, the proximity sensor overrides the screen state when an object is
|
// If true, the proximity sensor overrides the screen state when an object is
|
||||||
@ -75,6 +76,23 @@ final class DisplayPowerRequest {
|
|||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if we want the screen on in any mode, including doze.
|
||||||
|
public boolean wantScreenOnAny() {
|
||||||
|
return screenState != SCREEN_STATE_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if we want the screen on in a normal mode, excluding doze.
|
||||||
|
// This is usually what we want to tell the rest of the system. For compatibility
|
||||||
|
// reasons, we pretend the screen is off when dozing.
|
||||||
|
public boolean wantScreenOnNormal() {
|
||||||
|
return screenState == SCREEN_STATE_DIM || screenState == SCREEN_STATE_BRIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean wantLightSensorEnabled() {
|
||||||
|
// Specifically, we don't want the light sensor while dozing.
|
||||||
|
return useAutoBrightness && wantScreenOnNormal();
|
||||||
|
}
|
||||||
|
|
||||||
public void copyFrom(DisplayPowerRequest other) {
|
public void copyFrom(DisplayPowerRequest other) {
|
||||||
screenState = other.screenState;
|
screenState = other.screenState;
|
||||||
useProximitySensor = other.useProximitySensor;
|
useProximitySensor = other.useProximitySensor;
|
||||||
|
@ -83,7 +83,7 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
|
|
||||||
// Message: Sent when a user activity timeout occurs to update the power state.
|
// Message: Sent when a user activity timeout occurs to update the power state.
|
||||||
private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
|
private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
|
||||||
// Message: Sent when the device enters or exits a napping or dreaming state.
|
// Message: Sent when the device enters or exits a dreaming or dozing state.
|
||||||
private static final int MSG_SANDMAN = 2;
|
private static final int MSG_SANDMAN = 2;
|
||||||
// Message: Sent when the screen on blocker is released.
|
// Message: Sent when the screen on blocker is released.
|
||||||
private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
|
private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
|
||||||
@ -117,19 +117,21 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
|
|
||||||
// Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
|
// Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
|
||||||
// The screen should be off or in the process of being turned off by the display controller.
|
// The screen should be off or in the process of being turned off by the display controller.
|
||||||
|
// The device typically passes through the dozing state first.
|
||||||
private static final int WAKEFULNESS_ASLEEP = 0;
|
private static final int WAKEFULNESS_ASLEEP = 0;
|
||||||
// Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
|
// Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
|
||||||
// When the user activity timeout expires, the device may start napping or go to sleep.
|
// When the user activity timeout expires, the device may start dreaming or go to sleep.
|
||||||
private static final int WAKEFULNESS_AWAKE = 1;
|
private static final int WAKEFULNESS_AWAKE = 1;
|
||||||
// Wakefulness: The device is napping. It is deciding whether to dream or go to sleep
|
|
||||||
// but hasn't gotten around to it yet. It can be awoken by a call to wakeUp(), which
|
|
||||||
// ends the nap. User activity may brighten the screen but does not end the nap.
|
|
||||||
private static final int WAKEFULNESS_NAPPING = 2;
|
|
||||||
// Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
|
// Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
|
||||||
// which ends the dream. The device goes to sleep when goToSleep() is called, when
|
// which ends the dream. The device goes to sleep when goToSleep() is called, when
|
||||||
// the dream ends or when unplugged.
|
// the dream ends or when unplugged.
|
||||||
// User activity may brighten the screen but does not end the dream.
|
// User activity may brighten the screen but does not end the dream.
|
||||||
private static final int WAKEFULNESS_DREAMING = 3;
|
private static final int WAKEFULNESS_DREAMING = 2;
|
||||||
|
// Wakefulness: The device is dozing. It is almost asleep but is allowing a special
|
||||||
|
// low-power "doze" dream to run which keeps the display on but lets the application
|
||||||
|
// processor be suspended. It can be awoken by a call to wakeUp() which ends the dream.
|
||||||
|
// The device fully goes to sleep if the dream cannot be started or ends on its own.
|
||||||
|
private static final int WAKEFULNESS_DOZING = 3;
|
||||||
|
|
||||||
// Summarizes the state of all active wakelocks.
|
// Summarizes the state of all active wakelocks.
|
||||||
private static final int WAKE_LOCK_CPU = 1 << 0;
|
private static final int WAKE_LOCK_CPU = 1 << 0;
|
||||||
@ -138,6 +140,7 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
|
private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
|
||||||
private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
|
private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
|
||||||
private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
|
private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
|
||||||
|
private static final int WAKE_LOCK_DOZE = 1 << 6;
|
||||||
|
|
||||||
// Summarizes the user activity state.
|
// Summarizes the user activity state.
|
||||||
private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
|
private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
|
||||||
@ -164,11 +167,6 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
// Poll interval in milliseconds for watching boot animation finished.
|
// Poll interval in milliseconds for watching boot animation finished.
|
||||||
private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
|
private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
|
||||||
|
|
||||||
// If the battery level drops by this percentage and the user activity timeout
|
|
||||||
// has expired, then assume the device is receiving insufficient current to charge
|
|
||||||
// effectively and terminate the dream.
|
|
||||||
private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5;
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private LightsManager mLightsManager;
|
private LightsManager mLightsManager;
|
||||||
private BatteryService mBatteryService;
|
private BatteryService mBatteryService;
|
||||||
@ -195,6 +193,10 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
// This is distinct from the screen power state, which is managed separately.
|
// This is distinct from the screen power state, which is managed separately.
|
||||||
private int mWakefulness;
|
private int mWakefulness;
|
||||||
|
|
||||||
|
// True if the sandman has just been summoned for the first time since entering the
|
||||||
|
// dreaming or dozing state. Indicates whether a new dream should begin.
|
||||||
|
private boolean mSandmanSummoned;
|
||||||
|
|
||||||
// True if MSG_SANDMAN has been scheduled.
|
// True if MSG_SANDMAN has been scheduled.
|
||||||
private boolean mSandmanScheduled;
|
private boolean mSandmanScheduled;
|
||||||
|
|
||||||
@ -265,6 +267,14 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
// True if boot completed occurred. We keep the screen on until this happens.
|
// True if boot completed occurred. We keep the screen on until this happens.
|
||||||
private boolean mBootCompleted;
|
private boolean mBootCompleted;
|
||||||
|
|
||||||
|
// True if auto-suspend mode is enabled.
|
||||||
|
// Refer to autosuspend.h.
|
||||||
|
private boolean mAutoSuspendModeEnabled;
|
||||||
|
|
||||||
|
// True if interactive mode is enabled.
|
||||||
|
// Refer to power.h.
|
||||||
|
private boolean mInteractiveModeEnabled;
|
||||||
|
|
||||||
// True if the device is plugged into a power source.
|
// True if the device is plugged into a power source.
|
||||||
private boolean mIsPowered;
|
private boolean mIsPowered;
|
||||||
|
|
||||||
@ -282,6 +292,12 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
// The current dock state.
|
// The current dock state.
|
||||||
private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
|
private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
|
||||||
|
|
||||||
|
// True to decouple auto-suspend mode from the display state.
|
||||||
|
private boolean mDecoupleAutoSuspendModeFromDisplayConfig;
|
||||||
|
|
||||||
|
// True to decouple interactive mode from the display state.
|
||||||
|
private boolean mDecoupleInteractiveModeFromDisplayConfig;
|
||||||
|
|
||||||
// True if the device should wake up when plugged or unplugged.
|
// True if the device should wake up when plugged or unplugged.
|
||||||
private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
|
private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
|
||||||
|
|
||||||
@ -300,6 +316,22 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
// Default value for dreams activate-on-dock
|
// Default value for dreams activate-on-dock
|
||||||
private boolean mDreamsActivatedOnDockByDefaultConfig;
|
private boolean mDreamsActivatedOnDockByDefaultConfig;
|
||||||
|
|
||||||
|
// True if dreams can run while not plugged in.
|
||||||
|
private boolean mDreamsEnabledOnBatteryConfig;
|
||||||
|
|
||||||
|
// Minimum battery level to allow dreaming when powered.
|
||||||
|
// Use -1 to disable this safety feature.
|
||||||
|
private int mDreamsBatteryLevelMinimumWhenPoweredConfig;
|
||||||
|
|
||||||
|
// Minimum battery level to allow dreaming when not powered.
|
||||||
|
// Use -1 to disable this safety feature.
|
||||||
|
private int mDreamsBatteryLevelMinimumWhenNotPoweredConfig;
|
||||||
|
|
||||||
|
// If the battery level drops by this percentage and the user activity timeout
|
||||||
|
// has expired, then assume the device is receiving insufficient current to charge
|
||||||
|
// effectively and terminate the dream. Use -1 to disable this safety feature.
|
||||||
|
private int mDreamsBatteryLevelDrainCutoffConfig;
|
||||||
|
|
||||||
// True if dreams are enabled by the user.
|
// True if dreams are enabled by the user.
|
||||||
private boolean mDreamsEnabledSetting;
|
private boolean mDreamsEnabledSetting;
|
||||||
|
|
||||||
@ -523,6 +555,10 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
private void readConfigurationLocked() {
|
private void readConfigurationLocked() {
|
||||||
final Resources resources = mContext.getResources();
|
final Resources resources = mContext.getResources();
|
||||||
|
|
||||||
|
mDecoupleAutoSuspendModeFromDisplayConfig = resources.getBoolean(
|
||||||
|
com.android.internal.R.bool.config_powerDecoupleAutoSuspendModeFromDisplay);
|
||||||
|
mDecoupleInteractiveModeFromDisplayConfig = resources.getBoolean(
|
||||||
|
com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay);
|
||||||
mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
|
mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
|
||||||
com.android.internal.R.bool.config_unplugTurnsOnScreen);
|
com.android.internal.R.bool.config_unplugTurnsOnScreen);
|
||||||
mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
|
mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
|
||||||
@ -535,6 +571,14 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
|
com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
|
||||||
mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean(
|
mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean(
|
||||||
com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
|
com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
|
||||||
|
mDreamsEnabledOnBatteryConfig = resources.getBoolean(
|
||||||
|
com.android.internal.R.bool.config_dreamsEnabledOnBattery);
|
||||||
|
mDreamsBatteryLevelMinimumWhenPoweredConfig = resources.getInteger(
|
||||||
|
com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenPowered);
|
||||||
|
mDreamsBatteryLevelMinimumWhenNotPoweredConfig = resources.getInteger(
|
||||||
|
com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenNotPowered);
|
||||||
|
mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger(
|
||||||
|
com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSettingsLocked() {
|
private void updateSettingsLocked() {
|
||||||
@ -762,6 +806,7 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
case PowerManager.SCREEN_DIM_WAKE_LOCK:
|
case PowerManager.SCREEN_DIM_WAKE_LOCK:
|
||||||
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
|
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
|
||||||
case PowerManager.FULL_WAKE_LOCK:
|
case PowerManager.FULL_WAKE_LOCK:
|
||||||
|
case PowerManager.DOZE_WAKE_LOCK:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
|
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
|
||||||
@ -794,7 +839,8 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
|
if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
|
||||||
|| mWakefulness == WAKEFULNESS_ASLEEP || !mBootCompleted || !mSystemReady) {
|
|| mWakefulness == WAKEFULNESS_ASLEEP || mWakefulness == WAKEFULNESS_DOZING
|
||||||
|
|| !mBootCompleted || !mSystemReady) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,18 +889,21 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
switch (mWakefulness) {
|
switch (mWakefulness) {
|
||||||
case WAKEFULNESS_ASLEEP:
|
case WAKEFULNESS_ASLEEP:
|
||||||
Slog.i(TAG, "Waking up from sleep...");
|
Slog.i(TAG, "Waking up from sleep...");
|
||||||
sendPendingNotificationsLocked();
|
|
||||||
mNotifier.onWakeUpStarted();
|
|
||||||
mSendWakeUpFinishedNotificationWhenReady = true;
|
|
||||||
break;
|
break;
|
||||||
case WAKEFULNESS_DREAMING:
|
case WAKEFULNESS_DREAMING:
|
||||||
Slog.i(TAG, "Waking up from dream...");
|
Slog.i(TAG, "Waking up from dream...");
|
||||||
break;
|
break;
|
||||||
case WAKEFULNESS_NAPPING:
|
case WAKEFULNESS_DOZING:
|
||||||
Slog.i(TAG, "Waking up from nap...");
|
Slog.i(TAG, "Waking up from dozing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mWakefulness != WAKEFULNESS_DREAMING) {
|
||||||
|
sendPendingNotificationsLocked();
|
||||||
|
mNotifier.onWakeUpStarted();
|
||||||
|
mSendWakeUpFinishedNotificationWhenReady = true;
|
||||||
|
}
|
||||||
|
|
||||||
mLastWakeTime = eventTime;
|
mLastWakeTime = eventTime;
|
||||||
mWakefulness = WAKEFULNESS_AWAKE;
|
mWakefulness = WAKEFULNESS_AWAKE;
|
||||||
mDirty |= DIRTY_WAKEFULNESS;
|
mDirty |= DIRTY_WAKEFULNESS;
|
||||||
@ -877,13 +926,17 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method is called goToSleep for historical reasons but we actually start
|
||||||
|
// dozing before really going to sleep.
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
|
private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
|
||||||
if (DEBUG_SPEW) {
|
if (DEBUG_SPEW) {
|
||||||
Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
|
Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
|
if (eventTime < mLastWakeTime
|
||||||
|
|| mWakefulness == WAKEFULNESS_ASLEEP
|
||||||
|
|| mWakefulness == WAKEFULNESS_DOZING
|
||||||
|| !mBootCompleted || !mSystemReady) {
|
|| !mBootCompleted || !mSystemReady) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -907,7 +960,8 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
|
|
||||||
mLastSleepTime = eventTime;
|
mLastSleepTime = eventTime;
|
||||||
mDirty |= DIRTY_WAKEFULNESS;
|
mDirty |= DIRTY_WAKEFULNESS;
|
||||||
mWakefulness = WAKEFULNESS_ASLEEP;
|
mWakefulness = WAKEFULNESS_DOZING;
|
||||||
|
mSandmanSummoned = true;
|
||||||
|
|
||||||
// Report the number of wake locks that will be cleared by going to sleep.
|
// Report the number of wake locks that will be cleared by going to sleep.
|
||||||
int numWakeLocksCleared = 0;
|
int numWakeLocksCleared = 0;
|
||||||
@ -947,7 +1001,26 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
Slog.i(TAG, "Nap time...");
|
Slog.i(TAG, "Nap time...");
|
||||||
|
|
||||||
mDirty |= DIRTY_WAKEFULNESS;
|
mDirty |= DIRTY_WAKEFULNESS;
|
||||||
mWakefulness = WAKEFULNESS_NAPPING;
|
mWakefulness = WAKEFULNESS_DREAMING;
|
||||||
|
mSandmanSummoned = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done dozing, drop everything and go to sleep.
|
||||||
|
private boolean reallyGoToSleepNoUpdateLocked(long eventTime) {
|
||||||
|
if (DEBUG_SPEW) {
|
||||||
|
Slog.d(TAG, "reallyGoToSleepNoUpdateLocked: eventTime=" + eventTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
|
||||||
|
|| !mBootCompleted || !mSystemReady) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slog.i(TAG, "Sleeping...");
|
||||||
|
|
||||||
|
mDirty |= DIRTY_WAKEFULNESS;
|
||||||
|
mWakefulness = WAKEFULNESS_ASLEEP;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1023,7 +1096,7 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
mPlugType = mBatteryService.getPlugType();
|
mPlugType = mBatteryService.getPlugType();
|
||||||
mBatteryLevel = mBatteryService.getBatteryLevel();
|
mBatteryLevel = mBatteryService.getBatteryLevel();
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG_SPEW) {
|
||||||
Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
|
Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
|
||||||
+ ", mIsPowered=" + mIsPowered
|
+ ", mIsPowered=" + mIsPowered
|
||||||
+ ", oldPlugType=" + oldPlugType
|
+ ", oldPlugType=" + oldPlugType
|
||||||
@ -1083,8 +1156,7 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If already dreaming and becoming powered, then don't wake.
|
// If already dreaming and becoming powered, then don't wake.
|
||||||
if (mIsPowered && (mWakefulness == WAKEFULNESS_NAPPING
|
if (mIsPowered && mWakefulness == WAKEFULNESS_DREAMING) {
|
||||||
|| mWakefulness == WAKEFULNESS_DREAMING)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1131,35 +1203,45 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
mWakeLockSummary |= WAKE_LOCK_CPU;
|
mWakeLockSummary |= WAKE_LOCK_CPU;
|
||||||
break;
|
break;
|
||||||
case PowerManager.FULL_WAKE_LOCK:
|
case PowerManager.FULL_WAKE_LOCK:
|
||||||
if (mWakefulness != WAKEFULNESS_ASLEEP) {
|
if (mWakefulness == WAKEFULNESS_AWAKE
|
||||||
|
|| mWakefulness == WAKEFULNESS_DREAMING) {
|
||||||
mWakeLockSummary |= WAKE_LOCK_CPU
|
mWakeLockSummary |= WAKE_LOCK_CPU
|
||||||
| WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
|
| WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
|
||||||
if (mWakefulness == WAKEFULNESS_AWAKE) {
|
}
|
||||||
mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
|
if (mWakefulness == WAKEFULNESS_AWAKE) {
|
||||||
}
|
mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
|
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
|
||||||
if (mWakefulness != WAKEFULNESS_ASLEEP) {
|
if (mWakefulness == WAKEFULNESS_AWAKE
|
||||||
|
|| mWakefulness == WAKEFULNESS_DREAMING) {
|
||||||
mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT;
|
mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT;
|
||||||
if (mWakefulness == WAKEFULNESS_AWAKE) {
|
}
|
||||||
mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
|
if (mWakefulness == WAKEFULNESS_AWAKE) {
|
||||||
}
|
mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PowerManager.SCREEN_DIM_WAKE_LOCK:
|
case PowerManager.SCREEN_DIM_WAKE_LOCK:
|
||||||
if (mWakefulness != WAKEFULNESS_ASLEEP) {
|
if (mWakefulness == WAKEFULNESS_AWAKE
|
||||||
|
|| mWakefulness == WAKEFULNESS_DREAMING) {
|
||||||
mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_DIM;
|
mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_DIM;
|
||||||
if (mWakefulness == WAKEFULNESS_AWAKE) {
|
}
|
||||||
mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
|
if (mWakefulness == WAKEFULNESS_AWAKE) {
|
||||||
}
|
mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
|
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
|
||||||
if (mWakefulness != WAKEFULNESS_ASLEEP) {
|
if (mWakefulness == WAKEFULNESS_AWAKE
|
||||||
|
|| mWakefulness == WAKEFULNESS_DREAMING
|
||||||
|
|| mWakefulness == WAKEFULNESS_DOZING) {
|
||||||
mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
|
mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PowerManager.DOZE_WAKE_LOCK:
|
||||||
|
if (mWakefulness == WAKEFULNESS_DOZING) {
|
||||||
|
mWakeLockSummary |= WAKE_LOCK_DOZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1184,7 +1266,8 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
|
mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
|
||||||
|
|
||||||
long nextTimeout = 0;
|
long nextTimeout = 0;
|
||||||
if (mWakefulness != WAKEFULNESS_ASLEEP) {
|
if (mWakefulness == WAKEFULNESS_AWAKE
|
||||||
|
|| mWakefulness == WAKEFULNESS_DREAMING) {
|
||||||
final int screenOffTimeout = getScreenOffTimeoutLocked();
|
final int screenOffTimeout = getScreenOffTimeoutLocked();
|
||||||
final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
|
final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
|
||||||
|
|
||||||
@ -1205,8 +1288,7 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
&& mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
|
&& mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
|
||||||
nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
|
nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
|
||||||
if (now < nextTimeout
|
if (now < nextTimeout
|
||||||
&& mDisplayPowerRequest.screenState
|
&& mDisplayPowerRequest.wantScreenOnNormal()) {
|
||||||
!= DisplayPowerRequest.SCREEN_STATE_OFF) {
|
|
||||||
mUserActivitySummary = mDisplayPowerRequest.screenState
|
mUserActivitySummary = mDisplayPowerRequest.screenState
|
||||||
== DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
|
== DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
|
||||||
USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
|
USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
|
||||||
@ -1268,7 +1350,7 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
/**
|
/**
|
||||||
* Updates the wakefulness of the device.
|
* Updates the wakefulness of the device.
|
||||||
*
|
*
|
||||||
* This is the function that decides whether the device should start napping
|
* This is the function that decides whether the device should start dreaming
|
||||||
* based on the current wake locks and user activity state. It may modify mDirty
|
* based on the current wake locks and user activity state. It may modify mDirty
|
||||||
* if the wakefulness changes.
|
* if the wakefulness changes.
|
||||||
*
|
*
|
||||||
@ -1357,7 +1439,7 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the device enters or exits a napping or dreaming state.
|
* Called when the device enters or exits a dreaming or dozing state.
|
||||||
*
|
*
|
||||||
* We do this asynchronously because we must call out of the power manager to start
|
* We do this asynchronously because we must call out of the power manager to start
|
||||||
* the dream and we don't want to hold our lock while doing so. There is a risk that
|
* the dream and we don't want to hold our lock while doing so. There is a risk that
|
||||||
@ -1365,46 +1447,60 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
*/
|
*/
|
||||||
private void handleSandman() { // runs on handler thread
|
private void handleSandman() { // runs on handler thread
|
||||||
// Handle preconditions.
|
// Handle preconditions.
|
||||||
boolean startDreaming = false;
|
final boolean startDreaming;
|
||||||
|
final int wakefulness;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mSandmanScheduled = false;
|
mSandmanScheduled = false;
|
||||||
boolean canDream = canDreamLocked();
|
wakefulness = mWakefulness;
|
||||||
if (DEBUG_SPEW) {
|
if (mSandmanSummoned) {
|
||||||
Slog.d(TAG, "handleSandman: canDream=" + canDream
|
startDreaming = ((wakefulness == WAKEFULNESS_DREAMING && canDreamLocked())
|
||||||
+ ", mWakefulness=" + wakefulnessToString(mWakefulness));
|
|| wakefulness == WAKEFULNESS_DOZING);
|
||||||
}
|
mSandmanSummoned = false;
|
||||||
|
} else {
|
||||||
if (canDream && mWakefulness == WAKEFULNESS_NAPPING) {
|
startDreaming = false;
|
||||||
startDreaming = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start dreaming if needed.
|
// Start dreaming if needed.
|
||||||
// We only control the dream on the handler thread, so we don't need to worry about
|
// We only control the dream on the handler thread, so we don't need to worry about
|
||||||
// concurrent attempts to start or stop the dream.
|
// concurrent attempts to start or stop the dream.
|
||||||
boolean isDreaming = false;
|
final boolean isDreaming;
|
||||||
if (mDreamManager != null) {
|
if (mDreamManager != null) {
|
||||||
|
// Restart the dream whenever the sandman is summoned.
|
||||||
if (startDreaming) {
|
if (startDreaming) {
|
||||||
mDreamManager.startDream();
|
mDreamManager.stopDream();
|
||||||
|
mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);
|
||||||
}
|
}
|
||||||
isDreaming = mDreamManager.isDreaming();
|
isDreaming = mDreamManager.isDreaming();
|
||||||
|
} else {
|
||||||
|
isDreaming = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update dream state.
|
// Update dream state.
|
||||||
// We might need to stop the dream again if the preconditions changed.
|
|
||||||
boolean continueDreaming = false;
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (isDreaming && canDreamLocked()) {
|
// Remember the initial battery level when the dream started.
|
||||||
if (mWakefulness == WAKEFULNESS_NAPPING) {
|
if (startDreaming && isDreaming) {
|
||||||
mWakefulness = WAKEFULNESS_DREAMING;
|
mBatteryLevelWhenDreamStarted = mBatteryLevel;
|
||||||
mDirty |= DIRTY_WAKEFULNESS;
|
if (wakefulness == WAKEFULNESS_DOZING) {
|
||||||
mBatteryLevelWhenDreamStarted = mBatteryLevel;
|
Slog.i(TAG, "Dozing...");
|
||||||
updatePowerStateLocked();
|
} else {
|
||||||
continueDreaming = true;
|
Slog.i(TAG, "Dreaming...");
|
||||||
} else if (mWakefulness == WAKEFULNESS_DREAMING) {
|
}
|
||||||
if (!isBeingKeptAwakeLocked()
|
}
|
||||||
|
|
||||||
|
// If preconditions changed, wait for the next iteration to determine
|
||||||
|
// whether the dream should continue (or be restarted).
|
||||||
|
if (mSandmanSummoned || mWakefulness != wakefulness) {
|
||||||
|
return; // wait for next cycle
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine whether the dream should continue.
|
||||||
|
if (wakefulness == WAKEFULNESS_DREAMING) {
|
||||||
|
if (isDreaming && canDreamLocked()) {
|
||||||
|
if (mDreamsBatteryLevelDrainCutoffConfig >= 0
|
||||||
&& mBatteryLevel < mBatteryLevelWhenDreamStarted
|
&& mBatteryLevel < mBatteryLevelWhenDreamStarted
|
||||||
- DREAM_BATTERY_LEVEL_DRAIN_CUTOFF) {
|
- mDreamsBatteryLevelDrainCutoffConfig
|
||||||
|
&& !isBeingKeptAwakeLocked()) {
|
||||||
// If the user activity timeout expired and the battery appears
|
// If the user activity timeout expired and the battery appears
|
||||||
// to be draining faster than it is charging then stop dreaming
|
// to be draining faster than it is charging then stop dreaming
|
||||||
// and go to sleep.
|
// and go to sleep.
|
||||||
@ -1414,53 +1510,64 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
+ mBatteryLevelWhenDreamStarted + "%. "
|
+ mBatteryLevelWhenDreamStarted + "%. "
|
||||||
+ "Battery level now: " + mBatteryLevel + "%.");
|
+ "Battery level now: " + mBatteryLevel + "%.");
|
||||||
} else {
|
} else {
|
||||||
continueDreaming = true;
|
return; // continue dreaming
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!continueDreaming) {
|
// Dream has ended or will be stopped. Update the power state.
|
||||||
handleDreamFinishedLocked();
|
if (isItBedTimeYetLocked()) {
|
||||||
|
goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
|
||||||
|
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
|
||||||
|
updatePowerStateLocked();
|
||||||
|
} else {
|
||||||
|
wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
|
||||||
|
updatePowerStateLocked();
|
||||||
|
}
|
||||||
|
} else if (wakefulness == WAKEFULNESS_DOZING) {
|
||||||
|
if (isDreaming) {
|
||||||
|
return; // continue dozing
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doze has ended or will be stopped. Update the power state.
|
||||||
|
reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis());
|
||||||
|
updatePowerStateLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop dreaming if needed.
|
// Stop dream.
|
||||||
// It's possible that something else changed to make us need to start the dream again.
|
if (isDreaming) {
|
||||||
// If so, then the power manager will have posted another message to the handler
|
mDreamManager.stopDream();
|
||||||
// to take care of it later.
|
|
||||||
if (mDreamManager != null) {
|
|
||||||
if (!continueDreaming) {
|
|
||||||
mDreamManager.stopDream();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the device is allowed to dream in its current state
|
* Returns true if the device is allowed to dream in its current state.
|
||||||
* assuming that it is currently napping or dreaming.
|
* This function is not called when dozing.
|
||||||
*/
|
*/
|
||||||
private boolean canDreamLocked() {
|
private boolean canDreamLocked() {
|
||||||
return mDreamsSupportedConfig
|
if (mWakefulness != WAKEFULNESS_DREAMING
|
||||||
&& mDreamsEnabledSetting
|
|| !mDreamsSupportedConfig
|
||||||
&& mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
|
|| !mDreamsEnabledSetting
|
||||||
&& mBootCompleted
|
|| !mDisplayPowerRequest.wantScreenOnNormal()
|
||||||
&& (mIsPowered || isBeingKeptAwakeLocked());
|
|| !mBootCompleted) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
/**
|
if (!isBeingKeptAwakeLocked()) {
|
||||||
* Called when a dream is ending to figure out what to do next.
|
if (!mIsPowered && !mDreamsEnabledByDefaultConfig) {
|
||||||
*/
|
return false;
|
||||||
private void handleDreamFinishedLocked() {
|
}
|
||||||
if (mWakefulness == WAKEFULNESS_NAPPING
|
if (!mIsPowered
|
||||||
|| mWakefulness == WAKEFULNESS_DREAMING) {
|
&& mDreamsBatteryLevelMinimumWhenNotPoweredConfig >= 0
|
||||||
if (isItBedTimeYetLocked()) {
|
&& mBatteryLevel < mDreamsBatteryLevelMinimumWhenNotPoweredConfig) {
|
||||||
goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
|
return false;
|
||||||
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
|
}
|
||||||
updatePowerStateLocked();
|
if (mIsPowered
|
||||||
} else {
|
&& mDreamsBatteryLevelMinimumWhenPoweredConfig >= 0
|
||||||
wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
|
&& mBatteryLevel < mDreamsBatteryLevelMinimumWhenPoweredConfig) {
|
||||||
updatePowerStateLocked();
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleScreenOnBlockerReleased() {
|
private void handleScreenOnBlockerReleased() {
|
||||||
@ -1482,11 +1589,11 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
|
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
|
||||||
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
|
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
|
||||||
| DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
|
| DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
|
||||||
int newScreenState = getDesiredScreenPowerStateLocked();
|
final int newScreenState = getDesiredScreenPowerStateLocked();
|
||||||
if (newScreenState != mDisplayPowerRequest.screenState) {
|
if (newScreenState != mDisplayPowerRequest.screenState) {
|
||||||
mDisplayPowerRequest.screenState = newScreenState;
|
mDisplayPowerRequest.screenState = newScreenState;
|
||||||
nativeSetPowerState(
|
nativeSetPowerState(
|
||||||
newScreenState != DisplayPowerRequest.SCREEN_STATE_OFF,
|
mDisplayPowerRequest.wantScreenOnNormal(),
|
||||||
newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
|
newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1555,6 +1662,10 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
return DisplayPowerRequest.SCREEN_STATE_OFF;
|
return DisplayPowerRequest.SCREEN_STATE_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
|
||||||
|
return DisplayPowerRequest.SCREEN_STATE_DOZE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
|
if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
|
||||||
|| (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
|
|| (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
|
||||||
|| !mBootCompleted) {
|
|| !mBootCompleted) {
|
||||||
@ -1606,7 +1717,18 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
*/
|
*/
|
||||||
private void updateSuspendBlockerLocked() {
|
private void updateSuspendBlockerLocked() {
|
||||||
final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
|
final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
|
||||||
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlocker();
|
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
|
||||||
|
final boolean autoSuspend = !needDisplaySuspendBlocker;
|
||||||
|
|
||||||
|
// Disable auto-suspend if needed.
|
||||||
|
if (!autoSuspend) {
|
||||||
|
if (mDecoupleAutoSuspendModeFromDisplayConfig) {
|
||||||
|
setAutoSuspendModeLocked(false);
|
||||||
|
}
|
||||||
|
if (mDecoupleInteractiveModeFromDisplayConfig) {
|
||||||
|
setInteractiveModeLocked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// First acquire suspend blockers if needed.
|
// First acquire suspend blockers if needed.
|
||||||
if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
|
if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
|
||||||
@ -1627,17 +1749,27 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
mDisplaySuspendBlocker.release();
|
mDisplaySuspendBlocker.release();
|
||||||
mHoldingDisplaySuspendBlocker = false;
|
mHoldingDisplaySuspendBlocker = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable auto-suspend if needed.
|
||||||
|
if (autoSuspend) {
|
||||||
|
if (mDecoupleInteractiveModeFromDisplayConfig) {
|
||||||
|
setInteractiveModeLocked(false);
|
||||||
|
}
|
||||||
|
if (mDecoupleAutoSuspendModeFromDisplayConfig) {
|
||||||
|
setAutoSuspendModeLocked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if we must keep a suspend blocker active on behalf of the display.
|
* Return true if we must keep a suspend blocker active on behalf of the display.
|
||||||
* We do so if the screen is on or is in transition between states.
|
* We do so if the screen is on or is in transition between states.
|
||||||
*/
|
*/
|
||||||
private boolean needDisplaySuspendBlocker() {
|
private boolean needDisplaySuspendBlockerLocked() {
|
||||||
if (!mDisplayReady) {
|
if (!mDisplayReady) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
|
if (mDisplayPowerRequest.wantScreenOnNormal()) {
|
||||||
// If we asked for the screen to be on but it is off due to the proximity
|
// If we asked for the screen to be on but it is off due to the proximity
|
||||||
// sensor then we may suspend but only if the configuration allows it.
|
// sensor then we may suspend but only if the configuration allows it.
|
||||||
// On some hardware it may not be safe to suspend because the proximity
|
// On some hardware it may not be safe to suspend because the proximity
|
||||||
@ -1647,13 +1779,34 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Let the system suspend if the screen is off or dozing.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setAutoSuspendModeLocked(boolean enable) {
|
||||||
|
if (enable != mAutoSuspendModeEnabled) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.d(TAG, "Setting auto-suspend mode to " + enable);
|
||||||
|
}
|
||||||
|
mAutoSuspendModeEnabled = enable;
|
||||||
|
nativeSetAutoSuspend(enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setInteractiveModeLocked(boolean enable) {
|
||||||
|
if (enable != mInteractiveModeEnabled) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.d(TAG, "Setting interactive mode to " + enable);
|
||||||
|
}
|
||||||
|
mInteractiveModeEnabled = enable;
|
||||||
|
nativeSetInteractive(enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isScreenOnInternal() {
|
private boolean isScreenOnInternal() {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
return !mSystemReady
|
return !mSystemReady
|
||||||
|| mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
|
|| mDisplayPowerRequest.wantScreenOnNormal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1871,10 +2024,13 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
pw.println(" mProximityPositive=" + mProximityPositive);
|
pw.println(" mProximityPositive=" + mProximityPositive);
|
||||||
pw.println(" mBootCompleted=" + mBootCompleted);
|
pw.println(" mBootCompleted=" + mBootCompleted);
|
||||||
pw.println(" mSystemReady=" + mSystemReady);
|
pw.println(" mSystemReady=" + mSystemReady);
|
||||||
|
pw.println(" mAutoSuspendModeEnabled=" + mAutoSuspendModeEnabled);
|
||||||
|
pw.println(" mInteactiveModeEnabled=" + mInteractiveModeEnabled);
|
||||||
pw.println(" mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
|
pw.println(" mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
|
||||||
pw.println(" mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
|
pw.println(" mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
|
||||||
pw.println(" mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
|
pw.println(" mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
|
||||||
pw.println(" mSandmanScheduled=" + mSandmanScheduled);
|
pw.println(" mSandmanScheduled=" + mSandmanScheduled);
|
||||||
|
pw.println(" mSandmanSummoned=" + mSandmanSummoned);
|
||||||
pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
|
pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
|
||||||
pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
|
pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
|
||||||
pw.println(" mSendWakeUpFinishedNotificationWhenReady="
|
pw.println(" mSendWakeUpFinishedNotificationWhenReady="
|
||||||
@ -1890,6 +2046,10 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
|
|
||||||
pw.println();
|
pw.println();
|
||||||
pw.println("Settings and Configuration:");
|
pw.println("Settings and Configuration:");
|
||||||
|
pw.println(" mDecoupleAutoSuspendModeFromDisplayConfig="
|
||||||
|
+ mDecoupleAutoSuspendModeFromDisplayConfig);
|
||||||
|
pw.println(" mDecoupleInteractiveModeFromDisplayConfig="
|
||||||
|
+ mDecoupleInteractiveModeFromDisplayConfig);
|
||||||
pw.println(" mWakeUpWhenPluggedOrUnpluggedConfig="
|
pw.println(" mWakeUpWhenPluggedOrUnpluggedConfig="
|
||||||
+ mWakeUpWhenPluggedOrUnpluggedConfig);
|
+ mWakeUpWhenPluggedOrUnpluggedConfig);
|
||||||
pw.println(" mSuspendWhenScreenOffDueToProximityConfig="
|
pw.println(" mSuspendWhenScreenOffDueToProximityConfig="
|
||||||
@ -1900,6 +2060,14 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
+ mDreamsActivatedOnSleepByDefaultConfig);
|
+ mDreamsActivatedOnSleepByDefaultConfig);
|
||||||
pw.println(" mDreamsActivatedOnDockByDefaultConfig="
|
pw.println(" mDreamsActivatedOnDockByDefaultConfig="
|
||||||
+ mDreamsActivatedOnDockByDefaultConfig);
|
+ mDreamsActivatedOnDockByDefaultConfig);
|
||||||
|
pw.println(" mDreamsEnabledOnBatteryConfig="
|
||||||
|
+ mDreamsEnabledOnBatteryConfig);
|
||||||
|
pw.println(" mDreamsBatteryLevelMinimumWhenPoweredConfig="
|
||||||
|
+ mDreamsBatteryLevelMinimumWhenPoweredConfig);
|
||||||
|
pw.println(" mDreamsBatteryLevelMinimumWhenNotPoweredConfig="
|
||||||
|
+ mDreamsBatteryLevelMinimumWhenNotPoweredConfig);
|
||||||
|
pw.println(" mDreamsBatteryLevelDrainCutoffConfig="
|
||||||
|
+ mDreamsBatteryLevelDrainCutoffConfig);
|
||||||
pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
|
pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
|
||||||
pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
|
pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
|
||||||
pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
|
pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
|
||||||
@ -1975,8 +2143,8 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
return "Awake";
|
return "Awake";
|
||||||
case WAKEFULNESS_DREAMING:
|
case WAKEFULNESS_DREAMING:
|
||||||
return "Dreaming";
|
return "Dreaming";
|
||||||
case WAKEFULNESS_NAPPING:
|
case WAKEFULNESS_DOZING:
|
||||||
return "Napping";
|
return "Dozing";
|
||||||
default:
|
default:
|
||||||
return Integer.toString(wakefulness);
|
return Integer.toString(wakefulness);
|
||||||
}
|
}
|
||||||
@ -2153,6 +2321,7 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
+ " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
|
+ " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private String getLockLevelString() {
|
private String getLockLevelString() {
|
||||||
switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
|
switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
|
||||||
case PowerManager.FULL_WAKE_LOCK:
|
case PowerManager.FULL_WAKE_LOCK:
|
||||||
@ -2165,6 +2334,8 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
return "PARTIAL_WAKE_LOCK ";
|
return "PARTIAL_WAKE_LOCK ";
|
||||||
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
|
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
|
||||||
return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
|
return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
|
||||||
|
case PowerManager.DOZE_WAKE_LOCK:
|
||||||
|
return "DOZE_WAKE_LOCK ";
|
||||||
default:
|
default:
|
||||||
return "??? ";
|
return "??? ";
|
||||||
}
|
}
|
||||||
@ -2295,16 +2466,24 @@ public final class PowerManagerService extends com.android.server.SystemService
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
mBlanked = true;
|
mBlanked = true;
|
||||||
mDisplayManagerInternal.blankAllDisplaysFromPowerManager();
|
mDisplayManagerInternal.blankAllDisplaysFromPowerManager();
|
||||||
nativeSetInteractive(false);
|
if (!mDecoupleInteractiveModeFromDisplayConfig) {
|
||||||
nativeSetAutoSuspend(true);
|
setInteractiveModeLocked(false);
|
||||||
|
}
|
||||||
|
if (!mDecoupleAutoSuspendModeFromDisplayConfig) {
|
||||||
|
setAutoSuspendModeLocked(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unblankAllDisplays() {
|
public void unblankAllDisplays() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
nativeSetAutoSuspend(false);
|
if (!mDecoupleAutoSuspendModeFromDisplayConfig) {
|
||||||
nativeSetInteractive(true);
|
setAutoSuspendModeLocked(false);
|
||||||
|
}
|
||||||
|
if (!mDecoupleInteractiveModeFromDisplayConfig) {
|
||||||
|
setInteractiveModeLocked(true);
|
||||||
|
}
|
||||||
mDisplayManagerInternal.unblankAllDisplaysFromPowerManager();
|
mDisplayManagerInternal.unblankAllDisplaysFromPowerManager();
|
||||||
mBlanked = false;
|
mBlanked = false;
|
||||||
}
|
}
|
||||||
|
@ -364,8 +364,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
|
|||||||
* motion event processing when the screen is off since these events are normally
|
* motion event processing when the screen is off since these events are normally
|
||||||
* dropped. */
|
* dropped. */
|
||||||
@Override
|
@Override
|
||||||
public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
|
public int interceptMotionBeforeQueueingWhenScreenOff(long whenNanos, int policyFlags) {
|
||||||
return mService.mPolicy.interceptMotionBeforeQueueingWhenScreenOff(policyFlags);
|
return mService.mPolicy.interceptMotionBeforeQueueingWhenScreenOff(whenNanos, policyFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Provides an opportunity for the window manager policy to process a key before
|
/* Provides an opportunity for the window manager policy to process a key before
|
||||||
|
@ -6,6 +6,7 @@ LOCAL_SRC_FILES += \
|
|||||||
$(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
|
$(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
|
||||||
$(LOCAL_REL_DIR)/com_android_server_AssetAtlasService.cpp \
|
$(LOCAL_REL_DIR)/com_android_server_AssetAtlasService.cpp \
|
||||||
$(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
|
$(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
|
||||||
|
$(LOCAL_REL_DIR)/com_android_server_dreams_McuHal.cpp \
|
||||||
$(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp \
|
$(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp \
|
||||||
$(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \
|
$(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \
|
||||||
$(LOCAL_REL_DIR)/com_android_server_input_InputWindowHandle.cpp \
|
$(LOCAL_REL_DIR)/com_android_server_input_InputWindowHandle.cpp \
|
||||||
|
100
services/core/jni/com_android_server_dreams_McuHal.cpp
Normal file
100
services/core/jni/com_android_server_dreams_McuHal.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "McuHal"
|
||||||
|
|
||||||
|
//#define LOG_NDEBUG 0
|
||||||
|
|
||||||
|
#include "JNIHelp.h"
|
||||||
|
#include "jni.h"
|
||||||
|
|
||||||
|
#include <ScopedUtfChars.h>
|
||||||
|
#include <ScopedPrimitiveArray.h>
|
||||||
|
|
||||||
|
#include <utils/Errors.h>
|
||||||
|
#include <utils/Log.h>
|
||||||
|
#include <hardware/mcu.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
|
||||||
|
static jlong nativeOpen(JNIEnv* env, jclass clazz) {
|
||||||
|
mcu_module_t* module = NULL;
|
||||||
|
status_t err = hw_get_module(MCU_HARDWARE_MODULE_ID,
|
||||||
|
(hw_module_t const**)&module);
|
||||||
|
if (err) {
|
||||||
|
ALOGE("Couldn't load %s module (%s)", MCU_HARDWARE_MODULE_ID, strerror(-err));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = module->init(module);
|
||||||
|
if (err) {
|
||||||
|
ALOGE("Couldn't initialize %s module (%s)", MCU_HARDWARE_MODULE_ID, strerror(-err));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reinterpret_cast<jlong>(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
static jbyteArray nativeSendMessage(JNIEnv* env, jclass clazz,
|
||||||
|
jlong ptr, jstring msgStr, jbyteArray argArray) {
|
||||||
|
mcu_module_t* module = reinterpret_cast<mcu_module_t*>(ptr);
|
||||||
|
|
||||||
|
ScopedUtfChars msg(env, msgStr);
|
||||||
|
ALOGV("Sending message %s to MCU", msg.c_str());
|
||||||
|
|
||||||
|
void* result = NULL;
|
||||||
|
size_t resultSize = 0;
|
||||||
|
status_t err;
|
||||||
|
if (argArray) {
|
||||||
|
ScopedByteArrayRO arg(env, argArray);
|
||||||
|
err = module->sendMessage(module, msg.c_str(), arg.get(), arg.size(),
|
||||||
|
&result, &resultSize);
|
||||||
|
} else {
|
||||||
|
err = module->sendMessage(module, msg.c_str(), NULL, 0, &result, &resultSize);
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
ALOGE("Couldn't send message to MCU (%s)", strerror(-err));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jbyteArray resultArray = env->NewByteArray(resultSize);
|
||||||
|
if (resultArray) {
|
||||||
|
env->SetByteArrayRegion(resultArray, 0, resultSize, static_cast<jbyte*>(result));
|
||||||
|
}
|
||||||
|
free(result);
|
||||||
|
return resultArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JNINativeMethod gMcuHalMethods[] = {
|
||||||
|
/* name, signature, funcPtr */
|
||||||
|
{ "nativeOpen", "()J",
|
||||||
|
(void*) nativeOpen },
|
||||||
|
{ "nativeSendMessage", "(JLjava/lang/String;[B)[B",
|
||||||
|
(void*) nativeSendMessage },
|
||||||
|
};
|
||||||
|
|
||||||
|
int register_android_server_dreams_McuHal(JNIEnv* env) {
|
||||||
|
int res = jniRegisterNativeMethods(env, "com/android/server/dreams/McuHal",
|
||||||
|
gMcuHalMethods, NELEM(gMcuHalMethods));
|
||||||
|
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace android */
|
@ -144,8 +144,6 @@ static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t styl
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
WM_ACTION_PASS_TO_USER = 1,
|
WM_ACTION_PASS_TO_USER = 1,
|
||||||
WM_ACTION_WAKE_UP = 2,
|
|
||||||
WM_ACTION_GO_TO_SLEEP = 4,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -834,7 +832,7 @@ void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& p
|
|||||||
JNIEnv* env = jniEnv();
|
JNIEnv* env = jniEnv();
|
||||||
jint wmActions = env->CallIntMethod(mServiceObj,
|
jint wmActions = env->CallIntMethod(mServiceObj,
|
||||||
gServiceClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
|
gServiceClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
|
||||||
policyFlags);
|
when, policyFlags);
|
||||||
if (checkAndClearExceptionFromCallback(env,
|
if (checkAndClearExceptionFromCallback(env,
|
||||||
"interceptMotionBeforeQueueingWhenScreenOff")) {
|
"interceptMotionBeforeQueueingWhenScreenOff")) {
|
||||||
wmActions = 0;
|
wmActions = 0;
|
||||||
@ -850,20 +848,6 @@ void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& p
|
|||||||
|
|
||||||
void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
|
void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
|
||||||
uint32_t& policyFlags) {
|
uint32_t& policyFlags) {
|
||||||
if (wmActions & WM_ACTION_GO_TO_SLEEP) {
|
|
||||||
#if DEBUG_INPUT_DISPATCHER_POLICY
|
|
||||||
ALOGD("handleInterceptActions: Going to sleep.");
|
|
||||||
#endif
|
|
||||||
android_server_PowerManagerService_goToSleep(when);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wmActions & WM_ACTION_WAKE_UP) {
|
|
||||||
#if DEBUG_INPUT_DISPATCHER_POLICY
|
|
||||||
ALOGD("handleInterceptActions: Waking up.");
|
|
||||||
#endif
|
|
||||||
android_server_PowerManagerService_wakeUp(when);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wmActions & WM_ACTION_PASS_TO_USER) {
|
if (wmActions & WM_ACTION_PASS_TO_USER) {
|
||||||
policyFlags |= POLICY_FLAG_PASS_TO_USER;
|
policyFlags |= POLICY_FLAG_PASS_TO_USER;
|
||||||
} else {
|
} else {
|
||||||
@ -1402,7 +1386,7 @@ int register_android_server_InputManager(JNIEnv* env) {
|
|||||||
|
|
||||||
GET_METHOD_ID(gServiceClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
|
GET_METHOD_ID(gServiceClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
|
||||||
clazz,
|
clazz,
|
||||||
"interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
|
"interceptMotionBeforeQueueingWhenScreenOff", "(JI)I");
|
||||||
|
|
||||||
GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeDispatching, clazz,
|
GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeDispatching, clazz,
|
||||||
"interceptKeyBeforeDispatching",
|
"interceptKeyBeforeDispatching",
|
||||||
|
@ -36,6 +36,7 @@ int register_android_server_location_GpsLocationProvider(JNIEnv* env);
|
|||||||
int register_android_server_location_FlpHardwareProvider(JNIEnv* env);
|
int register_android_server_location_FlpHardwareProvider(JNIEnv* env);
|
||||||
int register_android_server_connectivity_Vpn(JNIEnv* env);
|
int register_android_server_connectivity_Vpn(JNIEnv* env);
|
||||||
int register_android_server_AssetAtlasService(JNIEnv* env);
|
int register_android_server_AssetAtlasService(JNIEnv* env);
|
||||||
|
int register_android_server_dreams_McuHal(JNIEnv* env);
|
||||||
};
|
};
|
||||||
|
|
||||||
using namespace android;
|
using namespace android;
|
||||||
@ -67,7 +68,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||||||
register_android_server_connectivity_Vpn(env);
|
register_android_server_connectivity_Vpn(env);
|
||||||
register_android_server_AssetAtlasService(env);
|
register_android_server_AssetAtlasService(env);
|
||||||
register_android_server_ConsumerIrService(env);
|
register_android_server_ConsumerIrService(env);
|
||||||
|
register_android_server_dreams_McuHal(env);
|
||||||
|
|
||||||
return JNI_VERSION_1_4;
|
return JNI_VERSION_1_4;
|
||||||
}
|
}
|
||||||
|
14
tests/DozeTest/Android.mk
Normal file
14
tests/DozeTest/Android.mk
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
# Only compile source java files in this apk.
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||||
|
|
||||||
|
LOCAL_PACKAGE_NAME := DozeTest
|
||||||
|
|
||||||
|
include $(BUILD_PACKAGE)
|
||||||
|
|
||||||
|
# Use the following include to make our test apk.
|
||||||
|
include $(call all-makefiles-under,$(LOCAL_PATH))
|
35
tests/DozeTest/AndroidManifest.xml
Normal file
35
tests/DozeTest/AndroidManifest.xml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2014 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.
|
||||||
|
-->
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.android.dreams.dozetest">
|
||||||
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
|
||||||
|
<application android:label="@string/app_name">
|
||||||
|
<service
|
||||||
|
android:name="DozeTestDream"
|
||||||
|
android:exported="true"
|
||||||
|
android:icon="@drawable/ic_app"
|
||||||
|
android:label="@string/doze_dream_name">
|
||||||
|
<!-- Commented out to prevent this dream from appearing in the list of
|
||||||
|
dreams that the user can select via the Settings application.
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.service.dreams.DreamService" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
-->
|
||||||
|
</service>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
BIN
tests/DozeTest/res/drawable-hdpi/ic_app.png
Executable file
BIN
tests/DozeTest/res/drawable-hdpi/ic_app.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
tests/DozeTest/res/drawable-mdpi/ic_app.png
Normal file
BIN
tests/DozeTest/res/drawable-mdpi/ic_app.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
41
tests/DozeTest/res/layout/dream.xml
Normal file
41
tests/DozeTest/res/layout/dream.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2014 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/alarm_clock_label" />
|
||||||
|
<TextView android:id="@+id/alarm_clock"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="32dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/tick_clock_label" />
|
||||||
|
<TextClock android:id="@+id/tick_clock"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
25
tests/DozeTest/res/values/strings.xml
Normal file
25
tests/DozeTest/res/values/strings.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2014 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.
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<!-- Name of the package of basic screensavers, shown in Settings > Apps. [CHAR LIMIT=40] -->
|
||||||
|
<string name="app_name">Doze Test</string>
|
||||||
|
|
||||||
|
<!-- Name of the screensaver. [CHAR LIMIT=40] -->
|
||||||
|
<string name="doze_dream_name">Doze Test</string>
|
||||||
|
|
||||||
|
<string name="alarm_clock_label">This clock is updated using the Alarm Manager</string>
|
||||||
|
<string name="tick_clock_label">This clock is updated using TIME_TICK Broadcasts</string>
|
||||||
|
</resources>
|
@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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 com.android.dreams.dozetest;
|
||||||
|
|
||||||
|
import android.app.AlarmManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.service.dreams.DozeHardware;
|
||||||
|
import android.service.dreams.DreamService;
|
||||||
|
import android.text.format.DateFormat;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple test for doze mode.
|
||||||
|
* <p>
|
||||||
|
* adb shell setprop debug.doze.component com.android.dreams.dozetest/.DozeTestDream
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public class DozeTestDream extends DreamService {
|
||||||
|
private static final String TAG = DozeTestDream.class.getSimpleName();
|
||||||
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
|
// Amount of time to allow to update the time shown on the screen before releasing
|
||||||
|
// the wakelock. This timeout is design to compensate for the fact that we don't
|
||||||
|
// currently have a way to know when time display contents have actually been
|
||||||
|
// refreshed once the dream has finished rendering a new frame.
|
||||||
|
private static final int UPDATE_TIME_TIMEOUT = 100;
|
||||||
|
|
||||||
|
// A doze hardware message string we use for end-to-end testing.
|
||||||
|
// Doesn't mean anything. Real hardware won't handle it.
|
||||||
|
private static final String TEST_PING_MESSAGE = "test.ping";
|
||||||
|
|
||||||
|
private PowerManager mPowerManager;
|
||||||
|
private PowerManager.WakeLock mWakeLock;
|
||||||
|
private AlarmManager mAlarmManager;
|
||||||
|
private PendingIntent mAlarmIntent;
|
||||||
|
|
||||||
|
private TextView mAlarmClock;
|
||||||
|
|
||||||
|
private final Date mTime = new Date();
|
||||||
|
private java.text.DateFormat mTimeFormat;
|
||||||
|
|
||||||
|
private boolean mDreaming;
|
||||||
|
private DozeHardware mDozeHardware;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
mPowerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
|
||||||
|
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||||
|
|
||||||
|
mAlarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
|
||||||
|
|
||||||
|
Intent intent = new Intent("com.android.dreams.dozetest.ACTION_ALARM");
|
||||||
|
intent.setPackage(getPackageName());
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(intent.getAction());
|
||||||
|
registerReceiver(mAlarmReceiver, filter);
|
||||||
|
mAlarmIntent = PendingIntent.getBroadcast(this, 0, intent,
|
||||||
|
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
unregisterReceiver(mAlarmReceiver);
|
||||||
|
mAlarmIntent.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
setInteractive(false);
|
||||||
|
setLowProfile(true);
|
||||||
|
setFullscreen(true);
|
||||||
|
setContentView(R.layout.dream);
|
||||||
|
|
||||||
|
mAlarmClock = (TextView)findViewById(R.id.alarm_clock);
|
||||||
|
|
||||||
|
mTimeFormat = DateFormat.getTimeFormat(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDreamingStarted() {
|
||||||
|
super.onDreamingStarted();
|
||||||
|
|
||||||
|
mDreaming = true;
|
||||||
|
mDozeHardware = getDozeHardware();
|
||||||
|
|
||||||
|
Log.d(TAG, "Dream started: canDoze=" + canDoze()
|
||||||
|
+ ", dozeHardware=" + mDozeHardware);
|
||||||
|
|
||||||
|
performTimeUpdate();
|
||||||
|
|
||||||
|
if (mDozeHardware != null) {
|
||||||
|
mDozeHardware.sendMessage(TEST_PING_MESSAGE, null);
|
||||||
|
mDozeHardware.setEnableMcu(true);
|
||||||
|
}
|
||||||
|
startDozing();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDreamingStopped() {
|
||||||
|
super.onDreamingStopped();
|
||||||
|
|
||||||
|
mDreaming = false;
|
||||||
|
if (mDozeHardware != null) {
|
||||||
|
mDozeHardware.setEnableMcu(false);
|
||||||
|
mDozeHardware = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Dream ended: isDozing=" + isDozing());
|
||||||
|
|
||||||
|
stopDozing();
|
||||||
|
cancelTimeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performTimeUpdate() {
|
||||||
|
if (mDreaming) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
now -= now % 60000; // back up to last minute boundary
|
||||||
|
|
||||||
|
mTime.setTime(now);
|
||||||
|
mAlarmClock.setText(mTimeFormat.format(mTime));
|
||||||
|
|
||||||
|
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, now + 60000, mAlarmIntent);
|
||||||
|
|
||||||
|
mWakeLock.acquire(UPDATE_TIME_TIMEOUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelTimeUpdate() {
|
||||||
|
mAlarmManager.cancel(mAlarmIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BroadcastReceiver mAlarmReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
performTimeUpdate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue
Block a user