* commit 'e4e71e1d06442726e23f8ccf66c75468634008c4': Power manager rewrite.
This commit is contained in:
@@ -16273,6 +16273,7 @@ package android.os {
|
||||
method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String);
|
||||
method public void reboot(java.lang.String);
|
||||
method public void userActivity(long, boolean);
|
||||
method public void wakeUp(long);
|
||||
field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
|
||||
field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a
|
||||
field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
|
||||
@@ -18763,7 +18764,7 @@ package android.provider {
|
||||
field public static final android.net.Uri DEFAULT_NOTIFICATION_URI;
|
||||
field public static final android.net.Uri DEFAULT_RINGTONE_URI;
|
||||
field public static final deprecated java.lang.String DEVICE_PROVISIONED = "device_provisioned";
|
||||
field public static final java.lang.String DIM_SCREEN = "dim_screen";
|
||||
field public static final deprecated java.lang.String DIM_SCREEN = "dim_screen";
|
||||
field public static final java.lang.String DTMF_TONE_WHEN_DIALING = "dtmf_tone";
|
||||
field public static final java.lang.String END_BUTTON_BEHAVIOR = "end_button_behavior";
|
||||
field public static final java.lang.String FONT_SCALE = "font_scale";
|
||||
|
||||
@@ -64,7 +64,7 @@ public class PowerCommand extends Svc.Command {
|
||||
= IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
|
||||
try {
|
||||
IBinder lock = new Binder();
|
||||
pm.acquireWakeLock(PowerManager.FULL_WAKE_LOCK, lock, "svc power", null);
|
||||
pm.acquireWakeLock(lock, PowerManager.FULL_WAKE_LOCK, "svc power", null);
|
||||
pm.setStayOnSetting(val);
|
||||
pm.releaseWakeLock(lock, 0);
|
||||
}
|
||||
|
||||
@@ -418,7 +418,8 @@ class ContextImpl extends Context {
|
||||
public Object createService(ContextImpl ctx) {
|
||||
IBinder b = ServiceManager.getService(POWER_SERVICE);
|
||||
IPowerManager service = IPowerManager.Stub.asInterface(b);
|
||||
return new PowerManager(service, ctx.mMainThread.getHandler());
|
||||
return new PowerManager(ctx.getOuterContext(),
|
||||
service, ctx.mMainThread.getHandler());
|
||||
}});
|
||||
|
||||
registerService(SEARCH_SERVICE, new ServiceFetcher() {
|
||||
|
||||
@@ -23,27 +23,33 @@ import android.os.WorkSource;
|
||||
|
||||
interface IPowerManager
|
||||
{
|
||||
// WARNING: changes in acquireWakeLock() signature must be reflected in IPowerManager.cpp/h
|
||||
void acquireWakeLock(int flags, IBinder lock, String tag, in WorkSource ws);
|
||||
void updateWakeLockWorkSource(IBinder lock, in WorkSource ws);
|
||||
void goToSleep(long time);
|
||||
void goToSleepWithReason(long time, int reason);
|
||||
// WARNING: changes in releaseWakeLock() signature must be reflected in IPowerManager.cpp/h
|
||||
// WARNING: The first two methods must remain the first two methods because their
|
||||
// transaction numbers must not change unless IPowerManager.cpp is also updated.
|
||||
void acquireWakeLock(IBinder lock, int flags, String tag, in WorkSource ws);
|
||||
void releaseWakeLock(IBinder lock, int flags);
|
||||
void userActivity(long when, boolean noChangeLights);
|
||||
void userActivityWithForce(long when, boolean noChangeLights, boolean force);
|
||||
void clearUserActivityTimeout(long now, long timeout);
|
||||
void setPokeLock(int pokey, IBinder lock, String tag);
|
||||
int getSupportedWakeLockFlags();
|
||||
void setStayOnSetting(int val);
|
||||
void setMaximumScreenOffTimeount(int timeMs);
|
||||
void preventScreenOn(boolean prevent);
|
||||
|
||||
void updateWakeLockWorkSource(IBinder lock, in WorkSource ws);
|
||||
boolean isWakeLockLevelSupported(int level);
|
||||
|
||||
void userActivity(long time, int event, int flags);
|
||||
void wakeUp(long time);
|
||||
void goToSleep(long time, int reason);
|
||||
|
||||
boolean isScreenOn();
|
||||
void reboot(String reason);
|
||||
void crash(String message);
|
||||
|
||||
// sets the brightness of the backlights (screen, keyboard, button) 0-255
|
||||
void setBacklightBrightness(int brightness);
|
||||
void clearUserActivityTimeout(long now, long timeout);
|
||||
void setPokeLock(int pokey, IBinder lock, String tag);
|
||||
void setStayOnSetting(int val);
|
||||
void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs);
|
||||
void preventScreenOn(boolean prevent);
|
||||
|
||||
// temporarily overrides the screen brightness settings to allow the user to
|
||||
// see the effect of a settings change without applying it immediately
|
||||
void setTemporaryScreenBrightnessSettingOverride(int brightness);
|
||||
void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj);
|
||||
|
||||
// sets the attention light (used by phone app only)
|
||||
void setAttentionLight(boolean on, int color);
|
||||
void setAutoBrightnessAdjustment(float adj);
|
||||
}
|
||||
|
||||
@@ -18,25 +18,11 @@ package android.os;
|
||||
|
||||
/** @hide */
|
||||
public interface LocalPowerManager {
|
||||
// FIXME: Replace poke locks with something else.
|
||||
|
||||
public static final int POKE_LOCK_IGNORE_TOUCH_EVENTS = 0x1;
|
||||
|
||||
public static final int POKE_LOCK_SHORT_TIMEOUT = 0x2;
|
||||
public static final int POKE_LOCK_MEDIUM_TIMEOUT = 0x4;
|
||||
public static final int POKE_LOCK_TIMEOUT_MASK = 0x6;
|
||||
|
||||
void goToSleep(long time);
|
||||
|
||||
// notify power manager when keyboard is opened/closed
|
||||
void setKeyboardVisibility(boolean visible);
|
||||
|
||||
// when the keyguard is up, it manages the power state, and userActivity doesn't do anything.
|
||||
void enableUserActivity(boolean enabled);
|
||||
|
||||
// the same as the method on PowerManager
|
||||
void userActivity(long time, boolean noChangeLights, int eventType);
|
||||
|
||||
boolean isScreenOn();
|
||||
|
||||
void setScreenBrightnessOverride(int brightness);
|
||||
void setButtonBrightnessOverride(int brightness);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.os;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
@@ -42,8 +43,8 @@ import android.util.Log;
|
||||
* wl.release();
|
||||
* }
|
||||
* </p><p>
|
||||
* The following flags are defined, with varying effects on system power.
|
||||
* <i>These flags are mutually exclusive - you may only specify one of them.</i>
|
||||
* The following wake lock levels are defined, with varying effects on system power.
|
||||
* <i>These levels are mutually exclusive - you may only specify one of them.</i>
|
||||
*
|
||||
* <table border="2" width="85%" align="center" frame="hsides" rules="rows">
|
||||
* <thead>
|
||||
@@ -177,7 +178,7 @@ public final class PowerManager {
|
||||
/**
|
||||
* Wake lock level: Turns the screen off when the proximity sensor activates.
|
||||
* <p>
|
||||
* Since not all devices have proximity sensors, use {@link #getSupportedWakeLockFlags}
|
||||
* Since not all devices have proximity sensors, use {@link #isWakeLockLevelSupported}
|
||||
* to determine whether this wake lock level is supported.
|
||||
* </p>
|
||||
*
|
||||
@@ -226,30 +227,25 @@ public final class PowerManager {
|
||||
*/
|
||||
public static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1;
|
||||
|
||||
/**
|
||||
* Brightness value to use when battery is low.
|
||||
* @hide
|
||||
*/
|
||||
public static final int BRIGHTNESS_LOW_BATTERY = 10;
|
||||
|
||||
/**
|
||||
* Brightness value for fully on.
|
||||
* @hide
|
||||
*/
|
||||
public static final int BRIGHTNESS_ON = 255;
|
||||
|
||||
/**
|
||||
* Brightness value for dim backlight.
|
||||
* @hide
|
||||
*/
|
||||
public static final int BRIGHTNESS_DIM = 20;
|
||||
|
||||
/**
|
||||
* Brightness value for fully off.
|
||||
* @hide
|
||||
*/
|
||||
public static final int BRIGHTNESS_OFF = 0;
|
||||
|
||||
/**
|
||||
* A nominal default brightness value.
|
||||
* Use {@link #getDefaultScreenBrightnessSetting()} instead.
|
||||
* @hide
|
||||
*/
|
||||
private static final int BRIGHTNESS_DEFAULT = 102;
|
||||
|
||||
// Note: Be sure to update android.os.BatteryStats and PowerManager.h
|
||||
// if adding or modifying user activity event constants.
|
||||
|
||||
@@ -271,17 +267,81 @@ public final class PowerManager {
|
||||
*/
|
||||
public static final int USER_ACTIVITY_EVENT_TOUCH = 2;
|
||||
|
||||
/**
|
||||
* User activity flag: Do not restart the user activity timeout or brighten
|
||||
* the display in response to user activity if it is already dimmed.
|
||||
* @hide
|
||||
*/
|
||||
public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0;
|
||||
|
||||
/**
|
||||
* Special wake lock tag used for the wake lock in the Window Manager that handles the
|
||||
* {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} flag.
|
||||
* @hide
|
||||
*/
|
||||
public static final String KEEP_SCREEN_ON_FLAG_TAG = "KEEP_SCREEN_ON_FLAG";
|
||||
|
||||
/**
|
||||
* Go to sleep reason code: Going to sleep due by user request.
|
||||
* @hide
|
||||
*/
|
||||
public static final int GO_TO_SLEEP_REASON_USER = 0;
|
||||
|
||||
/**
|
||||
* Go to sleep reason code: Going to sleep due by request of the
|
||||
* device administration policy.
|
||||
* @hide
|
||||
*/
|
||||
public static final int GO_TO_SLEEP_REASON_DEVICE_ADMIN = 1;
|
||||
|
||||
/**
|
||||
* Go to sleep reason code: Going to sleep due to a screen timeout.
|
||||
* @hide
|
||||
*/
|
||||
public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2;
|
||||
|
||||
final Context mContext;
|
||||
final IPowerManager mService;
|
||||
final Handler mHandler;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
public PowerManager(IPowerManager service, Handler handler) {
|
||||
public PowerManager(Context context, IPowerManager service, Handler handler) {
|
||||
mContext = context;
|
||||
mService = service;
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum supported screen brightness setting.
|
||||
* The screen may be allowed to become dimmer than this value but
|
||||
* this is the minimum value that can be set by the user.
|
||||
* @hide
|
||||
*/
|
||||
public int getMinimumScreenBrightnessSetting() {
|
||||
return mContext.getResources().getInteger(
|
||||
com.android.internal.R.integer.config_screenBrightnessDim);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum supported screen brightness setting.
|
||||
* The screen may be allowed to become dimmer than this value but
|
||||
* this is the maximum value that can be set by the user.
|
||||
* @hide
|
||||
*/
|
||||
public int getMaximumScreenBrightnessSetting() {
|
||||
return BRIGHTNESS_ON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default screen brightness setting.
|
||||
* @hide
|
||||
*/
|
||||
public int getDefaultScreenBrightnessSetting() {
|
||||
return BRIGHTNESS_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new wake lock with the specified level and flags.
|
||||
* <p>
|
||||
@@ -360,8 +420,10 @@ public final class PowerManager {
|
||||
/**
|
||||
* Notifies the power manager that user activity happened.
|
||||
* <p>
|
||||
* Turns the device from whatever state it's in to full on, and resets
|
||||
* the auto-off timer.
|
||||
* Resets the auto-off timer and brightens the screen if the device
|
||||
* is not asleep. This is what happens normally when a key or the touch
|
||||
* screen is pressed or when some other user activity occurs.
|
||||
* This method does not wake up the device if it has been put to sleep.
|
||||
* </p><p>
|
||||
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
|
||||
* </p>
|
||||
@@ -375,10 +437,14 @@ public final class PowerManager {
|
||||
* We want the device to stay on while the button is down, but we're about
|
||||
* to turn off the screen so we don't want the keyboard backlight to turn on again.
|
||||
* Otherwise the lights flash on and then off and it looks weird.
|
||||
*
|
||||
* @see #wakeUp
|
||||
* @see #goToSleep
|
||||
*/
|
||||
public void userActivity(long when, boolean noChangeLights) {
|
||||
try {
|
||||
mService.userActivity(when, noChangeLights);
|
||||
mService.userActivity(when, USER_ACTIVITY_EVENT_OTHER,
|
||||
noChangeLights ? USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS : 0);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
@@ -386,8 +452,8 @@ public final class PowerManager {
|
||||
/**
|
||||
* Forces the device to go to sleep.
|
||||
* <p>
|
||||
* Overrides all the wake locks that are held. This is what happen when the power
|
||||
* key is pressed to turn off the screen.
|
||||
* Overrides all the wake locks that are held.
|
||||
* This is what happens when the power key is pressed to turn off the screen.
|
||||
* </p><p>
|
||||
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
|
||||
* </p>
|
||||
@@ -396,10 +462,37 @@ public final class PowerManager {
|
||||
* {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
|
||||
* order the user activity with other power management functions. It should be set
|
||||
* to the timestamp of the input event that caused the request to go to sleep.
|
||||
*
|
||||
* @see #userActivity
|
||||
* @see #wakeUp
|
||||
*/
|
||||
public void goToSleep(long time) {
|
||||
try {
|
||||
mService.goToSleep(time);
|
||||
mService.goToSleep(time, GO_TO_SLEEP_REASON_USER);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the device to wake up from sleep.
|
||||
* <p>
|
||||
* If the device is currently asleep, wakes it up, otherwise does nothing.
|
||||
* This is what happens when the power key is pressed to turn on the screen.
|
||||
* </p><p>
|
||||
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
|
||||
* </p>
|
||||
*
|
||||
* @param time The time when the request to wake up was issued, in the
|
||||
* {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
|
||||
* order the user activity with other power management functions. It should be set
|
||||
* to the timestamp of the input event that caused the request to wake up.
|
||||
*
|
||||
* @see #userActivity
|
||||
* @see #goToSleep
|
||||
*/
|
||||
public void wakeUp(long time) {
|
||||
try {
|
||||
mService.wakeUp(time);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
@@ -416,34 +509,24 @@ public final class PowerManager {
|
||||
*/
|
||||
public void setBacklightBrightness(int brightness) {
|
||||
try {
|
||||
mService.setBacklightBrightness(brightness);
|
||||
mService.setTemporaryScreenBrightnessSettingOverride(brightness);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of wake lock levels and flags for {@link #newWakeLock}
|
||||
* that are supported on the device.
|
||||
* <p>
|
||||
* For example, to test to see if the {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK}
|
||||
* is supported:
|
||||
* {@samplecode
|
||||
* PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
* int supportedFlags = pm.getSupportedWakeLockFlags();
|
||||
* boolean proximitySupported = ((supportedFlags & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
|
||||
* == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK);
|
||||
* }
|
||||
* </p>
|
||||
* Returns true if the specified wake lock level is supported.
|
||||
*
|
||||
* @return The set of supported WakeLock flags.
|
||||
* @param level The wake lock level to check.
|
||||
* @return True if the specified wake lock level is supported.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public int getSupportedWakeLockFlags() {
|
||||
public boolean isWakeLockLevelSupported(int level) {
|
||||
try {
|
||||
return mService.getSupportedWakeLockFlags();
|
||||
return mService.isWakeLockLevelSupported(level);
|
||||
} catch (RemoteException e) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,7 +676,7 @@ public final class PowerManager {
|
||||
// been explicitly released by the keyguard.
|
||||
mHandler.removeCallbacks(mReleaser);
|
||||
try {
|
||||
mService.acquireWakeLock(mFlags, mToken, mTag, mWorkSource);
|
||||
mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
mHeld = true;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package android.os;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Describes the source of some work that may be done by someone else.
|
||||
* Currently the public representation of what a work source is is not
|
||||
@@ -313,6 +317,20 @@ public class WorkSource implements Parcelable {
|
||||
dest.writeIntArray(mUids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("{WorkSource: uids=[");
|
||||
for (int i = 0; i < mNum; i++) {
|
||||
if (i != 0) {
|
||||
result.append(", ");
|
||||
}
|
||||
result.append(mUids[i]);
|
||||
}
|
||||
result.append("]}");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<WorkSource> CREATOR
|
||||
= new Parcelable.Creator<WorkSource>() {
|
||||
public WorkSource createFromParcel(Parcel in) {
|
||||
|
||||
@@ -1381,7 +1381,9 @@ public final class Settings {
|
||||
|
||||
/**
|
||||
* Whether or not to dim the screen. 0=no 1=yes
|
||||
* @deprecated This setting is no longer used.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String DIM_SCREEN = "dim_screen";
|
||||
|
||||
/**
|
||||
|
||||
@@ -123,7 +123,9 @@ public class DreamManagerService
|
||||
// IDreamManager method
|
||||
@Override
|
||||
public boolean isDreaming() {
|
||||
return mCurrentDream != null;
|
||||
synchronized (mLock) {
|
||||
return mCurrentDreamToken != null;
|
||||
}
|
||||
}
|
||||
|
||||
public void bindDreamComponentL(ComponentName componentName, boolean test) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.util;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.os.SystemClock;
|
||||
import android.text.format.DateUtils;
|
||||
|
||||
import com.android.internal.util.XmlUtils;
|
||||
@@ -391,6 +392,18 @@ public class TimeUtils {
|
||||
formatDuration(time-now, pw, 0);
|
||||
}
|
||||
|
||||
/** @hide Just for debugging; not internationalized. */
|
||||
public static String formatUptime(long time) {
|
||||
final long diff = time - SystemClock.uptimeMillis();
|
||||
if (diff > 0) {
|
||||
return time + " (in " + diff + " ms)";
|
||||
}
|
||||
if (diff < 0) {
|
||||
return time + " (" + -diff + " ms ago)";
|
||||
}
|
||||
return time + " (now)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a System.currentTimeMillis() value to a time of day value like
|
||||
* that printed in logs. MM-DD HH:MM:SS.MMM
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.IBinder;
|
||||
import android.os.LocalPowerManager;
|
||||
import android.os.Looper;
|
||||
import android.view.animation.Animation;
|
||||
|
||||
@@ -115,11 +114,11 @@ public interface WindowManagerPolicy {
|
||||
public final static int ACTION_PASS_TO_USER = 0x00000001;
|
||||
|
||||
/**
|
||||
* This key event should extend the user activity timeout and turn the lights on.
|
||||
* 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_POKE_USER_ACTIVITY = 0x00000002;
|
||||
public final static int ACTION_WAKE_UP = 0x00000002;
|
||||
|
||||
/**
|
||||
* This key event should put the device to sleep (and engage keyguard if necessary)
|
||||
@@ -473,11 +472,9 @@ public interface WindowManagerPolicy {
|
||||
* Perform initialization of the policy.
|
||||
*
|
||||
* @param context The system context we are running in.
|
||||
* @param powerManager
|
||||
*/
|
||||
public void init(Context context, IWindowManager windowManager,
|
||||
WindowManagerFuncs windowManagerFuncs,
|
||||
LocalPowerManager powerManager);
|
||||
WindowManagerFuncs windowManagerFuncs);
|
||||
|
||||
/**
|
||||
* Called by window manager once it has the initial, default native
|
||||
@@ -1092,31 +1089,6 @@ public interface WindowManagerPolicy {
|
||||
*/
|
||||
public void lockNow();
|
||||
|
||||
/**
|
||||
* Check to see if a screensaver should be run instead of powering off the screen on timeout.
|
||||
*
|
||||
* @return true if the screensaver should run, false if the screen should turn off.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean isScreenSaverEnabled();
|
||||
|
||||
/**
|
||||
* Start the screensaver (if it is enabled and not yet running).
|
||||
*
|
||||
* @return Whether the screensaver was successfully started.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean startScreenSaver();
|
||||
|
||||
/**
|
||||
* Stop the screensaver if it is running.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void stopScreenSaver();
|
||||
|
||||
/**
|
||||
* Set the last used input method window state. This state is used to make IME transition
|
||||
* smooth.
|
||||
|
||||
@@ -500,19 +500,15 @@ public class ConnectivityManagerTestActivity extends Activity {
|
||||
log("Turn screen off");
|
||||
PowerManager pm =
|
||||
(PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
pm.goToSleep(SystemClock.uptimeMillis() + 100);
|
||||
pm.goToSleep(SystemClock.uptimeMillis());
|
||||
}
|
||||
|
||||
// Turn screen on
|
||||
public void turnScreenOn() {
|
||||
log("Turn screen on");
|
||||
IPowerManager mPowerManagerService = IPowerManager.Stub.asInterface(
|
||||
ServiceManager.getService("power"));;
|
||||
try {
|
||||
mPowerManagerService.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
|
||||
} catch (Exception e) {
|
||||
log(e.toString());
|
||||
}
|
||||
PowerManager pm =
|
||||
(PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
pm.wakeUp(SystemClock.uptimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,7 +49,7 @@ public class BrightnessLimit extends Activity implements OnClickListener {
|
||||
ServiceManager.getService("power"));
|
||||
if (power != null) {
|
||||
try {
|
||||
power.setBacklightBrightness(0);
|
||||
power.setTemporaryScreenBrightnessSettingOverride(0);
|
||||
} catch (RemoteException darn) {
|
||||
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class SettingsHelper {
|
||||
IPowerManager power = IPowerManager.Stub.asInterface(
|
||||
ServiceManager.getService("power"));
|
||||
if (power != null) {
|
||||
power.setBacklightBrightness(brightness);
|
||||
power.setTemporaryScreenBrightnessSettingOverride(brightness);
|
||||
}
|
||||
} catch (RemoteException doe) {
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.IPowerManager;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.provider.Settings;
|
||||
@@ -31,8 +32,8 @@ import android.widget.CompoundButton;
|
||||
public class BrightnessController implements ToggleSlider.Listener {
|
||||
private static final String TAG = "StatusBar.BrightnessController";
|
||||
|
||||
private static final int MINIMUM_BACKLIGHT = android.os.PowerManager.BRIGHTNESS_DIM;
|
||||
private static final int MAXIMUM_BACKLIGHT = android.os.PowerManager.BRIGHTNESS_ON;
|
||||
private final int mMinimumBacklight;
|
||||
private final int mMaximumBacklight;
|
||||
|
||||
private Context mContext;
|
||||
private ToggleSlider mControl;
|
||||
@@ -42,6 +43,10 @@ public class BrightnessController implements ToggleSlider.Listener {
|
||||
mContext = context;
|
||||
mControl = control;
|
||||
|
||||
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
|
||||
mMinimumBacklight = pm.getMinimumScreenBrightnessSetting();
|
||||
mMaximumBacklight = pm.getMaximumScreenBrightnessSetting();
|
||||
|
||||
boolean automaticAvailable = context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_automatic_brightness_available);
|
||||
mPower = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
|
||||
@@ -65,11 +70,11 @@ public class BrightnessController implements ToggleSlider.Listener {
|
||||
value = Settings.System.getInt(mContext.getContentResolver(),
|
||||
Settings.System.SCREEN_BRIGHTNESS);
|
||||
} catch (SettingNotFoundException ex) {
|
||||
value = MAXIMUM_BACKLIGHT;
|
||||
value = mMaximumBacklight;
|
||||
}
|
||||
|
||||
control.setMax(MAXIMUM_BACKLIGHT - MINIMUM_BACKLIGHT);
|
||||
control.setValue(value - MINIMUM_BACKLIGHT);
|
||||
control.setMax(mMaximumBacklight - mMinimumBacklight);
|
||||
control.setValue(value - mMinimumBacklight);
|
||||
|
||||
control.setOnChangedListener(this);
|
||||
}
|
||||
@@ -78,7 +83,7 @@ public class BrightnessController implements ToggleSlider.Listener {
|
||||
setMode(automatic ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
|
||||
: Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
|
||||
if (!automatic) {
|
||||
final int val = value + MINIMUM_BACKLIGHT;
|
||||
final int val = value + mMinimumBacklight;
|
||||
setBrightness(val);
|
||||
if (!tracking) {
|
||||
AsyncTask.execute(new Runnable() {
|
||||
@@ -98,7 +103,7 @@ public class BrightnessController implements ToggleSlider.Listener {
|
||||
|
||||
private void setBrightness(int brightness) {
|
||||
try {
|
||||
mPower.setBacklightBrightness(brightness);
|
||||
mPower.setTemporaryScreenBrightnessSettingOverride(brightness);
|
||||
} catch (RemoteException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.media.SoundPool;
|
||||
import android.os.Handler;
|
||||
import android.os.LocalPowerManager;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManager;
|
||||
@@ -157,10 +156,6 @@ public class KeyguardViewMediator implements KeyguardViewCallback {
|
||||
private boolean mSuppressNextLockSound = true;
|
||||
|
||||
|
||||
/** Low level access to the power manager for enableUserActivity. Having this
|
||||
* requires that we run in the system process. */
|
||||
LocalPowerManager mRealPowerManager;
|
||||
|
||||
/** High level access to the power manager for WakeLocks */
|
||||
private PowerManager mPM;
|
||||
|
||||
@@ -358,11 +353,9 @@ public class KeyguardViewMediator implements KeyguardViewCallback {
|
||||
|
||||
};
|
||||
|
||||
public KeyguardViewMediator(Context context, PhoneWindowManager callback,
|
||||
LocalPowerManager powerManager) {
|
||||
public KeyguardViewMediator(Context context, PhoneWindowManager callback) {
|
||||
mContext = context;
|
||||
mCallback = callback;
|
||||
mRealPowerManager = powerManager;
|
||||
mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = mPM.newWakeLock(
|
||||
PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "keyguard");
|
||||
@@ -1034,7 +1027,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback {
|
||||
if (DEBUG) Log.d(TAG, "handleKeyguardDone");
|
||||
handleHide();
|
||||
if (wakeup) {
|
||||
mPM.userActivity(SystemClock.uptimeMillis(), true);
|
||||
mPM.wakeUp(SystemClock.uptimeMillis());
|
||||
}
|
||||
mWakeLock.release();
|
||||
mContext.sendBroadcast(mUserPresentIntent);
|
||||
@@ -1167,7 +1160,8 @@ public class KeyguardViewMediator implements KeyguardViewCallback {
|
||||
// disable user activity if we are shown and not hidden
|
||||
if (DEBUG) Log.d(TAG, "adjustUserActivityLocked mShowing: " + mShowing + " mHidden: " + mHidden);
|
||||
boolean enabled = !mShowing || mHidden;
|
||||
mRealPowerManager.enableUserActivity(enabled);
|
||||
// FIXME: Replace this with a new timeout control mechanism.
|
||||
//mRealPowerManager.enableUserActivity(enabled);
|
||||
if (!enabled && mScreenOn) {
|
||||
// reinstate our short screen timeout policy
|
||||
pokeWakelock();
|
||||
|
||||
@@ -45,7 +45,6 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.LocalPowerManager;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
@@ -170,9 +169,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
|
||||
static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
|
||||
|
||||
// Should screen savers use their own timeout, or the SCREEN_OFF_TIMEOUT?
|
||||
static final boolean SEPARATE_TIMEOUT_FOR_SCREEN_SAVER = false;
|
||||
|
||||
static final int LONG_PRESS_POWER_NOTHING = 0;
|
||||
static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
|
||||
static final int LONG_PRESS_POWER_SHUT_OFF = 2;
|
||||
@@ -280,7 +276,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
Context mContext;
|
||||
IWindowManager mWindowManager;
|
||||
WindowManagerFuncs mWindowManagerFuncs;
|
||||
LocalPowerManager mPowerManager;
|
||||
PowerManager mPowerManager;
|
||||
IStatusBarService mStatusBarService;
|
||||
final Object mServiceAquireLock = new Object();
|
||||
Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
|
||||
@@ -474,13 +470,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
int mLockScreenTimeout;
|
||||
boolean mLockScreenTimerActive;
|
||||
|
||||
// visual screen saver support
|
||||
boolean mScreenSaverFeatureAvailable;
|
||||
int mScreenSaverTimeout = 0;
|
||||
boolean mScreenSaverEnabledByUser = false;
|
||||
boolean mScreenSaverMayRun = true; // false if a wakelock is held
|
||||
boolean mPluggedIn;
|
||||
|
||||
// Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.)
|
||||
int mEndcallBehavior;
|
||||
|
||||
@@ -572,12 +561,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
|
||||
resolver.registerContentObserver(Settings.System.getUriFor(
|
||||
"fancy_rotation_anim"), false, this);
|
||||
resolver.registerContentObserver(Settings.Secure.getUriFor(
|
||||
Settings.Secure.SCREENSAVER_ENABLED), false, this);
|
||||
if (SEPARATE_TIMEOUT_FOR_SCREEN_SAVER) {
|
||||
resolver.registerContentObserver(Settings.Secure.getUriFor(
|
||||
"screensaver_timeout"), false, this);
|
||||
} // otherwise SCREEN_OFF_TIMEOUT will do nicely
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
@@ -863,16 +846,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void init(Context context, IWindowManager windowManager,
|
||||
WindowManagerFuncs windowManagerFuncs,
|
||||
LocalPowerManager powerManager) {
|
||||
WindowManagerFuncs windowManagerFuncs) {
|
||||
mContext = context;
|
||||
mWindowManager = windowManager;
|
||||
mWindowManagerFuncs = windowManagerFuncs;
|
||||
mPowerManager = powerManager;
|
||||
mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
|
||||
if (!mHeadless) {
|
||||
// don't create KeyguardViewMediator if headless
|
||||
mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);
|
||||
mKeyguardMediator = new KeyguardViewMediator(context, this);
|
||||
}
|
||||
mHandler = new PolicyHandler();
|
||||
mOrientationListener = new MyOrientationListener(mContext);
|
||||
@@ -898,8 +879,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||
|
||||
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
|
||||
mBroadcastWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
|
||||
mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
"PhoneWindowManager.mBroadcastWakeLock");
|
||||
mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
|
||||
mLidOpenRotation = readRotation(
|
||||
@@ -932,14 +913,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
Intent.EXTRA_DOCK_STATE_UNDOCKED);
|
||||
}
|
||||
|
||||
// watch the plug to know whether to trigger the screen saver
|
||||
filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
intent = context.registerReceiver(mPowerReceiver, filter);
|
||||
if (intent != null) {
|
||||
mPluggedIn = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
|
||||
}
|
||||
|
||||
mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
mLongPressVibePattern = getLongIntArray(mContext.getResources(),
|
||||
com.android.internal.R.array.config_longPressVibePattern);
|
||||
@@ -1121,26 +1094,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mHasSoftInput = hasSoftInput;
|
||||
updateRotation = true;
|
||||
}
|
||||
|
||||
// dreams
|
||||
mScreenSaverFeatureAvailable = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_enableDreams);
|
||||
|
||||
mScreenSaverEnabledByUser = 0 != Settings.Secure.getInt(resolver,
|
||||
Settings.Secure.SCREENSAVER_ENABLED, 0);
|
||||
|
||||
if (SEPARATE_TIMEOUT_FOR_SCREEN_SAVER) {
|
||||
mScreenSaverTimeout = Settings.Secure.getInt(resolver,
|
||||
"screensaver_timeout", 0);
|
||||
} else {
|
||||
mScreenSaverTimeout = Settings.System.getInt(resolver,
|
||||
Settings.System.SCREEN_OFF_TIMEOUT, 0);
|
||||
if (mScreenSaverTimeout > 0) {
|
||||
// We actually want to activate the screensaver just before the
|
||||
// power manager's screen timeout
|
||||
mScreenSaverTimeout -= 5000;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updateRotation) {
|
||||
updateRotation(true);
|
||||
@@ -3018,12 +2971,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(
|
||||
KeyEvent.KEYCODE_POWER, mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED);
|
||||
} else {
|
||||
mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
|
||||
PowerManager.USER_ACTIVITY_EVENT_BUTTON);
|
||||
mPowerManager.wakeUp(SystemClock.uptimeMillis());
|
||||
}
|
||||
} else if (!mLidControlsSleep) {
|
||||
mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
|
||||
PowerManager.USER_ACTIVITY_EVENT_OTHER);
|
||||
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3182,6 +3133,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
|
||||
if (!mSystemBooted) {
|
||||
// If we have not yet booted, don't let key events do anything.
|
||||
return 0;
|
||||
}
|
||||
|
||||
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
|
||||
final boolean canceled = event.isCanceled();
|
||||
final int keyCode = event.getKeyCode();
|
||||
@@ -3197,14 +3153,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mKeyguardMediator.isShowingAndNotHidden() :
|
||||
mKeyguardMediator.isShowing()));
|
||||
|
||||
if (!mSystemBooted) {
|
||||
// If we have not yet booted, don't let key events do anything.
|
||||
return 0;
|
||||
if (keyCode == KeyEvent.KEYCODE_POWER) {
|
||||
policyFlags |= WindowManagerPolicy.FLAG_WAKE;
|
||||
}
|
||||
final boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
|
||||
| WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
|
||||
|
||||
if (DEBUG_INPUT) {
|
||||
Log.d(TAG, "interceptKeyTq keycode=" + keyCode
|
||||
+ " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive);
|
||||
+ " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive
|
||||
+ " policyFlags=" + Integer.toHexString(policyFlags)
|
||||
+ " isWakeKey=" + isWakeKey);
|
||||
}
|
||||
|
||||
if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
|
||||
@@ -3212,12 +3171,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_POWER) {
|
||||
policyFlags |= WindowManagerPolicy.FLAG_WAKE;
|
||||
}
|
||||
final boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
|
||||
| WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
|
||||
|
||||
// Basic policy based on screen state and keyguard.
|
||||
// FIXME: This policy isn't quite correct. We shouldn't care whether the screen
|
||||
// is on or off, really. We should care about whether the device is in an
|
||||
@@ -3241,7 +3194,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED);
|
||||
} else {
|
||||
// Otherwise, wake the device ourselves.
|
||||
result |= ACTION_POKE_USER_ACTIVITY;
|
||||
result |= ACTION_WAKE_UP;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3346,7 +3299,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
if ((mEndcallBehavior
|
||||
& Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
|
||||
result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
|
||||
result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3388,7 +3341,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mPowerKeyTriggered = false;
|
||||
cancelPendingScreenshotChordAction();
|
||||
if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
|
||||
result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
|
||||
result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
|
||||
}
|
||||
mPendingPowerKeyUpCanceled = false;
|
||||
}
|
||||
@@ -3473,7 +3426,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mKeyguardMediator.onWakeMotionWhenKeyguardShowingTq();
|
||||
} else {
|
||||
// Otherwise, wake the device ourselves.
|
||||
result |= ACTION_POKE_USER_ACTIVITY;
|
||||
result |= ACTION_WAKE_UP;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -3553,15 +3506,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
};
|
||||
|
||||
BroadcastReceiver mPowerReceiver = new BroadcastReceiver() {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
|
||||
mPluggedIn = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
|
||||
if (localLOGV) Log.v(TAG, "BATTERY_CHANGED: " + intent + " plugged=" + mPluggedIn);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void screenTurnedOff(int why) {
|
||||
EventLog.writeEvent(70000, 0);
|
||||
@@ -4035,62 +3979,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
private IDreamManager getDreamManager() {
|
||||
if (!mScreenSaverFeatureAvailable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IDreamManager sandman = IDreamManager.Stub.asInterface(
|
||||
ServiceManager.checkService("dreams"));
|
||||
if (sandman == null) {
|
||||
Log.w(TAG, "Unable to find IDreamManager");
|
||||
}
|
||||
return sandman;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScreenSaverEnabled() {
|
||||
return (mScreenSaverFeatureAvailable && mScreenSaverEnabledByUser
|
||||
&& mScreenSaverMayRun && mScreenOnEarly && mPluggedIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startScreenSaver() {
|
||||
synchronized (mLock) {
|
||||
if (isScreenSaverEnabled()) {
|
||||
IDreamManager dm = getDreamManager();
|
||||
if (dm == null) return false;
|
||||
|
||||
try {
|
||||
if (localLOGV) Log.v(TAG, "startScreenSaver: entering dreamland...");
|
||||
|
||||
dm.dream();
|
||||
return true;
|
||||
} catch (RemoteException ex) {
|
||||
// too bad, so sad, oh mom, oh dad
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopScreenSaver() {
|
||||
synchronized (mLock) {
|
||||
IDreamManager dm = getDreamManager();
|
||||
if (dm == null) return;
|
||||
|
||||
try {
|
||||
if (!dm.isDreaming()) return;
|
||||
|
||||
if (localLOGV) Log.v(TAG, "stopScreenSaver: awakening...");
|
||||
|
||||
dm.awaken();
|
||||
} catch (RemoteException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Runnable mScreenLockTimeout = new Runnable() {
|
||||
public void run() {
|
||||
synchronized (this) {
|
||||
@@ -4134,8 +4022,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
|
||||
private void applyLidSwitchState() {
|
||||
mPowerManager.setKeyboardVisibility(isBuiltInKeyboardVisible());
|
||||
|
||||
if (mLidState == LID_CLOSED && mLidControlsSleep) {
|
||||
mPowerManager.goToSleep(SystemClock.uptimeMillis());
|
||||
}
|
||||
@@ -4317,24 +4203,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
|
||||
public void screenOnStartedLw() {
|
||||
// The window manager has just grabbed a wake lock. This is our cue to disable the screen
|
||||
// saver.
|
||||
synchronized (mLock) {
|
||||
mScreenSaverMayRun = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void screenOnStoppedLw() {
|
||||
if (mPowerManager.isScreenOn()) {
|
||||
if (mKeyguardMediator != null && !mKeyguardMediator.isShowingAndNotHidden()) {
|
||||
long curTime = SystemClock.uptimeMillis();
|
||||
mPowerManager.userActivity(curTime, false, PowerManager.USER_ACTIVITY_EVENT_OTHER);
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
// even if the keyguard is up, now that all the wakelocks have been released, we
|
||||
// should re-enable the screen saver
|
||||
mScreenSaverMayRun = true;
|
||||
mPowerManager.userActivity(curTime, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1626,7 +1626,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
mLastMaximumTimeToLock = timeMs;
|
||||
|
||||
try {
|
||||
getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
|
||||
getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failure talking with power manager", e);
|
||||
}
|
||||
@@ -1667,8 +1667,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
// Power off the display
|
||||
mIPowerManager.goToSleepWithReason(SystemClock.uptimeMillis(),
|
||||
WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN);
|
||||
getIPowerManager().goToSleep(SystemClock.uptimeMillis(),
|
||||
PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN);
|
||||
// Ensure the device is locked
|
||||
getWindowManager().lockNow();
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UEventObserver;
|
||||
import android.provider.Settings;
|
||||
@@ -64,11 +65,8 @@ class DockObserver extends UEventObserver {
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private PowerManagerService mPowerManager;
|
||||
|
||||
public DockObserver(Context context, PowerManagerService pm) {
|
||||
public DockObserver(Context context) {
|
||||
mContext = context;
|
||||
mPowerManager = pm;
|
||||
init(); // set initial status
|
||||
|
||||
startObserving(DOCK_UEVENT_MATCH);
|
||||
@@ -94,8 +92,9 @@ class DockObserver extends UEventObserver {
|
||||
&& mPreviousDockState != Intent.EXTRA_DOCK_STATE_LE_DESK
|
||||
&& mPreviousDockState != Intent.EXTRA_DOCK_STATE_HE_DESK) ||
|
||||
mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
|
||||
mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(),
|
||||
false, true);
|
||||
PowerManager pm =
|
||||
(PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
|
||||
pm.wakeUp(SystemClock.uptimeMillis());
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.android.internal.os.SamplingProfilerIntegration;
|
||||
import com.android.internal.widget.LockSettingsService;
|
||||
import com.android.server.accessibility.AccessibilityManagerService;
|
||||
import com.android.server.am.ActivityManagerService;
|
||||
import com.android.server.am.BatteryStatsService;
|
||||
import com.android.server.display.DisplayManagerService;
|
||||
import com.android.server.input.InputManagerService;
|
||||
import com.android.server.net.NetworkPolicyManagerService;
|
||||
@@ -230,7 +231,8 @@ class ServerThread extends Thread {
|
||||
|
||||
// only initialize the power service after we have started the
|
||||
// lights service, content providers and the battery service.
|
||||
power.init(context, lights, ActivityManagerService.self(), battery, display);
|
||||
power.init(context, lights, ActivityManagerService.self(), battery,
|
||||
BatteryStatsService.getService(), display);
|
||||
|
||||
Slog.i(TAG, "Alarm Manager");
|
||||
alarm = new AlarmManagerService(context);
|
||||
@@ -553,7 +555,7 @@ class ServerThread extends Thread {
|
||||
try {
|
||||
Slog.i(TAG, "Dock Observer");
|
||||
// Listen for dock station changes
|
||||
dock = new DockObserver(context, power);
|
||||
dock = new DockObserver(context);
|
||||
} catch (Throwable e) {
|
||||
reportWtf("starting DockObserver", e);
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ public class Watchdog extends Thread {
|
||||
}
|
||||
|
||||
if (mMinScreenOff >= 0 && (mPower == null ||
|
||||
mPower.timeSinceScreenOn() < mMinScreenOff)) {
|
||||
mPower.timeSinceScreenWasLastOn() < mMinScreenOff)) {
|
||||
return "screen";
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,992 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.power;
|
||||
|
||||
import com.android.server.LightsService;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.SystemSensorManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Slog;
|
||||
import android.util.TimeUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Controls the power state of the display.
|
||||
*
|
||||
* Handles the proximity sensor, light sensor, and animations between states
|
||||
* including the screen off animation.
|
||||
*
|
||||
* This component acts independently of the rest of the power manager service.
|
||||
* In particular, it does not share any state and it only communicates
|
||||
* via asynchronous callbacks to inform the power manager that something has
|
||||
* changed.
|
||||
*
|
||||
* Everything this class does internally is serialized on its handler although
|
||||
* it may be accessed by other threads from the outside.
|
||||
*
|
||||
* Note that the power manager service guarantees that it will hold a suspend
|
||||
* blocker as long as the display is not ready. So most of the work done here
|
||||
* does not need to worry about holding a suspend blocker unless it happens
|
||||
* independently of the display ready signal.
|
||||
*
|
||||
* For debugging, you can make the electron beam and brightness animations run
|
||||
* slower by changing the "animator duration scale" option in Development Settings.
|
||||
*/
|
||||
final class DisplayPowerController {
|
||||
private static final String TAG = "DisplayPowerController";
|
||||
|
||||
private static boolean DEBUG = false;
|
||||
private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
|
||||
private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false;
|
||||
|
||||
private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 300;
|
||||
private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 600;
|
||||
|
||||
private static final int MSG_UPDATE_POWER_STATE = 1;
|
||||
private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
|
||||
private static final int MSG_LIGHT_SENSOR_DEBOUNCED = 3;
|
||||
|
||||
private static final int PROXIMITY_UNKNOWN = -1;
|
||||
private static final int PROXIMITY_NEGATIVE = 0;
|
||||
private static final int PROXIMITY_POSITIVE = 1;
|
||||
|
||||
// Proximity sensor debounce delay in milliseconds.
|
||||
private static final int PROXIMITY_SENSOR_DEBOUNCE_DELAY = 250;
|
||||
|
||||
// Trigger proximity if distance is less than 5 cm.
|
||||
private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
|
||||
|
||||
// Light sensor event rate in microseconds.
|
||||
private static final int LIGHT_SENSOR_RATE = 1000000;
|
||||
|
||||
// Brightness animation ramp rate in brightness units per second.
|
||||
private static final int BRIGHTNESS_RAMP_RATE_FAST = 200;
|
||||
private static final int BRIGHTNESS_RAMP_RATE_SLOW = 50;
|
||||
|
||||
// Filter time constant in milliseconds for computing a moving
|
||||
// average of light samples. Different constants are used
|
||||
// to adapt to brighter or dimmer environments.
|
||||
private static final long BRIGHTENING_LIGHT_TIME_CONSTANT = 2500; // 2.5 sec
|
||||
private static final long DIMMING_LIGHT_TIME_CONSTANT = 10000; // 10 sec
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
// Notifier for sending asynchronous notifications.
|
||||
private final Notifier mNotifier;
|
||||
|
||||
// A suspend blocker.
|
||||
private final SuspendBlocker mSuspendBlocker;
|
||||
|
||||
// Our handler.
|
||||
private final DisplayControllerHandler mHandler;
|
||||
|
||||
// Asynchronous callbacks into the power manager service.
|
||||
// Only invoked from the handler thread while no locks are held.
|
||||
private final Callbacks mCallbacks;
|
||||
private Handler mCallbackHandler;
|
||||
|
||||
// The lights service.
|
||||
private final LightsService mLights;
|
||||
|
||||
// The sensor manager.
|
||||
private final SensorManager mSensorManager;
|
||||
|
||||
// The proximity sensor, or null if not available or needed.
|
||||
private Sensor mProximitySensor;
|
||||
|
||||
// The light sensor, or null if not available or needed.
|
||||
private Sensor mLightSensor;
|
||||
|
||||
// The dim screen brightness.
|
||||
private final int mScreenBrightnessDimConfig;
|
||||
|
||||
// Auto-brightness.
|
||||
private boolean mUseSoftwareAutoBrightnessConfig;
|
||||
private int[] mAutoBrightnessLevelsConfig;
|
||||
private int[] mAutoBrightnessLcdBacklightValuesConfig;
|
||||
|
||||
// Amount of time to delay auto-brightness after screen on while waiting for
|
||||
// the light sensor to warm-up in milliseconds.
|
||||
// May be 0 if no warm-up is required.
|
||||
private int mLightSensorWarmUpTimeConfig;
|
||||
|
||||
// The pending power request.
|
||||
// Initially null until the first call to requestPowerState.
|
||||
// Guarded by mLock.
|
||||
private DisplayPowerRequest mPendingRequestLocked;
|
||||
|
||||
// True if a request has been made to wait for the proximity sensor to go negative.
|
||||
// Guarded by mLock.
|
||||
private boolean mPendingWaitForNegativeProximityLocked;
|
||||
|
||||
// True if the pending power request or wait for negative proximity flag
|
||||
// has been changed since the last update occurred.
|
||||
// Guarded by mLock.
|
||||
private boolean mPendingRequestChangedLocked;
|
||||
|
||||
// Set to true when the important parts of the pending power request have been applied.
|
||||
// The important parts are mainly the screen state. Brightness changes may occur
|
||||
// concurrently.
|
||||
// Guarded by mLock.
|
||||
private boolean mDisplayReadyLocked;
|
||||
|
||||
// Set to true if a power state update is required.
|
||||
// Guarded by mLock.
|
||||
private boolean mPendingUpdatePowerStateLocked;
|
||||
|
||||
/* The following state must only be accessed by the handler thread. */
|
||||
|
||||
// The currently requested power state.
|
||||
// The power controller will progressively update its internal state to match
|
||||
// the requested power state. Initially null until the first update.
|
||||
private DisplayPowerRequest mPowerRequest;
|
||||
|
||||
// The current power state.
|
||||
// Must only be accessed on the handler thread.
|
||||
private DisplayPowerState mPowerState;
|
||||
|
||||
// True if the device should wait for negative proximity sensor before
|
||||
// waking up the screen. This is set to false as soon as a negative
|
||||
// proximity sensor measurement is observed or when the device is forced to
|
||||
// go to sleep by the user. While true, the screen remains off.
|
||||
private boolean mWaitingForNegativeProximity;
|
||||
|
||||
// The actual proximity sensor threshold value.
|
||||
private float mProximityThreshold;
|
||||
|
||||
// Set to true if the proximity sensor listener has been registered
|
||||
// with the sensor manager.
|
||||
private boolean mProximitySensorEnabled;
|
||||
|
||||
// The debounced proximity sensor state.
|
||||
private int mProximity = PROXIMITY_UNKNOWN;
|
||||
|
||||
// The raw non-debounced proximity sensor state.
|
||||
private int mPendingProximity = PROXIMITY_UNKNOWN;
|
||||
private long mPendingProximityDebounceTime;
|
||||
|
||||
// True if the screen was turned off because of the proximity sensor.
|
||||
// When the screen turns on again, we report user activity to the power manager.
|
||||
private boolean mScreenOffBecauseOfProximity;
|
||||
|
||||
// Set to true if the light sensor is enabled.
|
||||
private boolean mLightSensorEnabled;
|
||||
|
||||
// The time when the light sensor was enabled.
|
||||
private long mLightSensorEnableTime;
|
||||
|
||||
// The currently accepted average light sensor value.
|
||||
private float mLightMeasurement;
|
||||
|
||||
// True if the light sensor measurement is valid.
|
||||
private boolean mLightMeasurementValid;
|
||||
|
||||
// The number of light sensor samples that have been collected since the
|
||||
// last time a light sensor reading was accepted.
|
||||
private int mRecentLightSamples;
|
||||
|
||||
// The moving average of recent light sensor values.
|
||||
private float mRecentLightAverage;
|
||||
|
||||
// True if recent light samples are getting brighter than the previous
|
||||
// stable light measurement.
|
||||
private boolean mRecentLightBrightening;
|
||||
|
||||
// The time constant to use for filtering based on whether the
|
||||
// light appears to be brightening or dimming.
|
||||
private long mRecentLightTimeConstant;
|
||||
|
||||
// The most recent light sample.
|
||||
private float mLastLightSample;
|
||||
|
||||
// The time of the most light recent sample.
|
||||
private long mLastLightSampleTime;
|
||||
|
||||
// The upcoming debounce light sensor time.
|
||||
// This is only valid when mLightMeasurementValue && mRecentLightSamples >= 1.
|
||||
private long mPendingLightSensorDebounceTime;
|
||||
|
||||
// The screen brightness level that has been chosen by the auto-brightness
|
||||
// algorithm. The actual brightness should ramp towards this value.
|
||||
// We preserve this value even when we stop using the light sensor so
|
||||
// that we can quickly revert to the previous auto-brightness level
|
||||
// while the light sensor warms up.
|
||||
// Use -1 if there is no current auto-brightness value available.
|
||||
private int mScreenAutoBrightness = -1;
|
||||
|
||||
// True if the screen auto-brightness value is actually being used to
|
||||
// set the display brightness.
|
||||
private boolean mUsingScreenAutoBrightness;
|
||||
|
||||
// Animators.
|
||||
private ObjectAnimator mElectronBeamOnAnimator;
|
||||
private ObjectAnimator mElectronBeamOffAnimator;
|
||||
private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
|
||||
|
||||
/**
|
||||
* Creates the display power controller.
|
||||
*/
|
||||
public DisplayPowerController(Looper looper, Context context, Notifier notifier,
|
||||
LightsService lights, SuspendBlocker suspendBlocker,
|
||||
Callbacks callbacks, Handler callbackHandler) {
|
||||
mHandler = new DisplayControllerHandler(looper);
|
||||
mNotifier = notifier;
|
||||
mSuspendBlocker = suspendBlocker;
|
||||
mCallbacks = callbacks;
|
||||
mCallbackHandler = callbackHandler;
|
||||
|
||||
mLights = lights;
|
||||
mSensorManager = new SystemSensorManager(mHandler.getLooper());
|
||||
|
||||
final Resources resources = context.getResources();
|
||||
mScreenBrightnessDimConfig = resources.getInteger(
|
||||
com.android.internal.R.integer.config_screenBrightnessDim);
|
||||
mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
|
||||
com.android.internal.R.bool.config_automatic_brightness_available);
|
||||
if (mUseSoftwareAutoBrightnessConfig) {
|
||||
mAutoBrightnessLevelsConfig = resources.getIntArray(
|
||||
com.android.internal.R.array.config_autoBrightnessLevels);
|
||||
mAutoBrightnessLcdBacklightValuesConfig = resources.getIntArray(
|
||||
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
|
||||
if (mAutoBrightnessLcdBacklightValuesConfig.length
|
||||
!= mAutoBrightnessLevelsConfig.length + 1) {
|
||||
Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "
|
||||
+ "(size " + mAutoBrightnessLcdBacklightValuesConfig.length + ") "
|
||||
+ "should have exactly one more entry than "
|
||||
+ "config_autoBrightnessLevels (size "
|
||||
+ mAutoBrightnessLevelsConfig.length + "). "
|
||||
+ "Auto-brightness will be disabled.");
|
||||
mUseSoftwareAutoBrightnessConfig = false;
|
||||
}
|
||||
|
||||
mLightSensorWarmUpTimeConfig = resources.getInteger(
|
||||
com.android.internal.R.integer.config_lightSensorWarmupTime);
|
||||
}
|
||||
|
||||
if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
|
||||
mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
||||
if (mProximitySensor != null) {
|
||||
mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
|
||||
TYPICAL_PROXIMITY_THRESHOLD);
|
||||
}
|
||||
}
|
||||
|
||||
if (mUseSoftwareAutoBrightnessConfig
|
||||
&& !DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
|
||||
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the proximity sensor screen-off function is available.
|
||||
*/
|
||||
public boolean isProximitySensorAvailable() {
|
||||
return mProximitySensor != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a new power state.
|
||||
* The controller makes a copy of the provided object and then
|
||||
* begins adjusting the power state to match what was requested.
|
||||
*
|
||||
* @param request The requested power state.
|
||||
* @param waitForNegativeProximity If true, issues a request to wait for
|
||||
* negative proximity before turning the screen back on, assuming the screen
|
||||
* was turned off by the proximity sensor.
|
||||
* @return True if display is ready, false if there are important changes that must
|
||||
* be made asynchronously (such as turning the screen on), in which case the caller
|
||||
* should grab a wake lock, watch for {@link Callbacks#onStateChanged()} then try
|
||||
* the request again later until the state converges.
|
||||
*/
|
||||
public boolean requestPowerState(DisplayPowerRequest request,
|
||||
boolean waitForNegativeProximity) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "requestPowerState: "
|
||||
+ request + ", waitForNegativeProximity=" + waitForNegativeProximity);
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
boolean changed = false;
|
||||
|
||||
if (waitForNegativeProximity
|
||||
&& !mPendingWaitForNegativeProximityLocked) {
|
||||
mPendingWaitForNegativeProximityLocked = true;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (mPendingRequestLocked == null) {
|
||||
mPendingRequestLocked = new DisplayPowerRequest(request);
|
||||
changed = true;
|
||||
} else if (!mPendingRequestLocked.equals(request)) {
|
||||
mPendingRequestLocked.copyFrom(request);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
mDisplayReadyLocked = false;
|
||||
}
|
||||
|
||||
if (changed && !mPendingRequestChangedLocked) {
|
||||
mPendingRequestChangedLocked = true;
|
||||
sendUpdatePowerStateLocked();
|
||||
}
|
||||
|
||||
return mDisplayReadyLocked;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendUpdatePowerState() {
|
||||
synchronized (mLock) {
|
||||
sendUpdatePowerStateLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendUpdatePowerStateLocked() {
|
||||
if (!mPendingUpdatePowerStateLocked) {
|
||||
mPendingUpdatePowerStateLocked = true;
|
||||
Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
final Executor executor = AsyncTask.THREAD_POOL_EXECUTOR;
|
||||
mPowerState = new DisplayPowerState(new ElectronBeam(),
|
||||
new PhotonicModulator(executor,
|
||||
mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT),
|
||||
mSuspendBlocker));
|
||||
|
||||
mElectronBeamOnAnimator = ObjectAnimator.ofFloat(
|
||||
mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f);
|
||||
mElectronBeamOnAnimator.setDuration(ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS);
|
||||
mElectronBeamOnAnimator.addListener(mAnimatorListener);
|
||||
|
||||
mElectronBeamOffAnimator = ObjectAnimator.ofFloat(
|
||||
mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 1.0f, 0.0f);
|
||||
mElectronBeamOffAnimator.setDuration(ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS);
|
||||
mElectronBeamOffAnimator.addListener(mAnimatorListener);
|
||||
|
||||
mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
|
||||
mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
|
||||
}
|
||||
|
||||
private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
}
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
sendUpdatePowerState();
|
||||
}
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
}
|
||||
};
|
||||
|
||||
private void updatePowerState() {
|
||||
// Update the power state request.
|
||||
final boolean mustNotify;
|
||||
boolean mustInitialize = false;
|
||||
synchronized (mLock) {
|
||||
mPendingUpdatePowerStateLocked = false;
|
||||
if (mPendingRequestLocked == null) {
|
||||
return; // wait until first actual power request
|
||||
}
|
||||
|
||||
if (mPowerRequest == null) {
|
||||
mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
|
||||
mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
|
||||
mPendingRequestChangedLocked = false;
|
||||
mustInitialize = true;
|
||||
} else if (mPendingRequestChangedLocked) {
|
||||
mPowerRequest.copyFrom(mPendingRequestLocked);
|
||||
mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
|
||||
mPendingRequestChangedLocked = false;
|
||||
mDisplayReadyLocked = false;
|
||||
}
|
||||
|
||||
mustNotify = !mDisplayReadyLocked;
|
||||
}
|
||||
|
||||
// Initialize things the first time the power state is changed.
|
||||
if (mustInitialize) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
// Clear a request to wait for negative proximity if needed.
|
||||
if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_OFF
|
||||
|| mProximity == PROXIMITY_NEGATIVE
|
||||
|| mProximitySensor == null) {
|
||||
mWaitingForNegativeProximity = false;
|
||||
}
|
||||
|
||||
// Turn on the proximity sensor if needed.
|
||||
if (mProximitySensor != null) {
|
||||
setProximitySensorEnabled(mPowerRequest.useProximitySensor
|
||||
|| mWaitingForNegativeProximity);
|
||||
if (mProximitySensorEnabled && mProximity == PROXIMITY_POSITIVE) {
|
||||
mScreenOffBecauseOfProximity = true;
|
||||
setScreenOn(false);
|
||||
} else if (mScreenOffBecauseOfProximity) {
|
||||
mScreenOffBecauseOfProximity = false;
|
||||
sendOnProximityNegative();
|
||||
}
|
||||
}
|
||||
|
||||
// Turn on the light sensor if needed.
|
||||
if (mLightSensor != null) {
|
||||
setLightSensorEnabled(mPowerRequest.useAutoBrightness
|
||||
&& wantScreenOn(mPowerRequest.screenState));
|
||||
}
|
||||
|
||||
// Set the screen brightness.
|
||||
if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {
|
||||
// Screen is dimmed. Overrides everything else.
|
||||
animateScreenBrightness(mScreenBrightnessDimConfig, BRIGHTNESS_RAMP_RATE_FAST);
|
||||
mUsingScreenAutoBrightness = false;
|
||||
} else if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT) {
|
||||
if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) {
|
||||
// Use current auto-brightness value.
|
||||
animateScreenBrightness(
|
||||
Math.max(mScreenAutoBrightness, mScreenBrightnessDimConfig),
|
||||
mUsingScreenAutoBrightness ? BRIGHTNESS_RAMP_RATE_SLOW :
|
||||
BRIGHTNESS_RAMP_RATE_FAST);
|
||||
mUsingScreenAutoBrightness = true;
|
||||
} else {
|
||||
// Light sensor is disabled or not ready yet.
|
||||
// Use the current brightness setting from the request, which is expected
|
||||
// provide a nominal default value for the case where auto-brightness
|
||||
// is not ready yet.
|
||||
animateScreenBrightness(
|
||||
Math.max(mPowerRequest.screenBrightness, mScreenBrightnessDimConfig),
|
||||
BRIGHTNESS_RAMP_RATE_FAST);
|
||||
mUsingScreenAutoBrightness = false;
|
||||
}
|
||||
} else {
|
||||
// Screen is off. Don't bother changing the brightness.
|
||||
mUsingScreenAutoBrightness = false;
|
||||
}
|
||||
|
||||
// Animate the screen on or off.
|
||||
if (!mScreenOffBecauseOfProximity) {
|
||||
if (wantScreenOn(mPowerRequest.screenState)) {
|
||||
// Want screen on.
|
||||
// Wait for previous off animation to complete beforehand.
|
||||
// It is relatively short but if we cancel it and switch to the
|
||||
// on animation immediately then the results are pretty ugly.
|
||||
if (!mElectronBeamOffAnimator.isStarted()) {
|
||||
setScreenOn(true);
|
||||
if (!mElectronBeamOnAnimator.isStarted()) {
|
||||
if (mPowerState.getElectronBeamLevel() == 1.0f) {
|
||||
mPowerState.dismissElectronBeam();
|
||||
} else if (mPowerState.prepareElectronBeam(true)) {
|
||||
mElectronBeamOnAnimator.start();
|
||||
} else {
|
||||
mElectronBeamOnAnimator.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Want screen off.
|
||||
// Wait for previous on animation to complete beforehand.
|
||||
if (!mElectronBeamOnAnimator.isStarted()) {
|
||||
if (!mElectronBeamOffAnimator.isStarted()) {
|
||||
if (mPowerState.getElectronBeamLevel() == 0.0f) {
|
||||
setScreenOn(false);
|
||||
} else if (mPowerState.prepareElectronBeam(false)
|
||||
&& mPowerState.isScreenOn()) {
|
||||
mElectronBeamOffAnimator.start();
|
||||
} else {
|
||||
mElectronBeamOffAnimator.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report whether the display is ready for use.
|
||||
// We mostly care about the screen state here, ignoring brightness changes
|
||||
// which will be handled asynchronously.
|
||||
if (mustNotify
|
||||
&& !mElectronBeamOnAnimator.isStarted()
|
||||
&& !mElectronBeamOffAnimator.isStarted()
|
||||
&& mPowerState.waitUntilClean(mCleanListener)) {
|
||||
synchronized (mLock) {
|
||||
if (!mPendingRequestChangedLocked) {
|
||||
mDisplayReadyLocked = true;
|
||||
}
|
||||
}
|
||||
sendOnStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void setScreenOn(boolean on) {
|
||||
if (!mPowerState.isScreenOn() == on) {
|
||||
mPowerState.setScreenOn(on);
|
||||
if (on) {
|
||||
mNotifier.onScreenOn();
|
||||
} else {
|
||||
mNotifier.onScreenOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void animateScreenBrightness(int target, int rate) {
|
||||
if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
|
||||
mNotifier.onScreenBrightness(target);
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable mCleanListener = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
sendUpdatePowerState();
|
||||
}
|
||||
};
|
||||
|
||||
private void setProximitySensorEnabled(boolean enable) {
|
||||
if (enable) {
|
||||
if (!mProximitySensorEnabled) {
|
||||
mProximitySensorEnabled = true;
|
||||
mPendingProximity = PROXIMITY_UNKNOWN;
|
||||
mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
|
||||
SensorManager.SENSOR_DELAY_NORMAL, mHandler);
|
||||
}
|
||||
} else {
|
||||
if (mProximitySensorEnabled) {
|
||||
mProximitySensorEnabled = false;
|
||||
mProximity = PROXIMITY_UNKNOWN;
|
||||
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
mSensorManager.unregisterListener(mProximitySensorListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleProximitySensorEvent(long time, boolean positive) {
|
||||
if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
|
||||
return; // no change
|
||||
}
|
||||
if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
|
||||
return; // no change
|
||||
}
|
||||
|
||||
// Only accept a proximity sensor reading if it remains
|
||||
// stable for the entire debounce delay.
|
||||
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
mPendingProximity = positive ? PROXIMITY_POSITIVE : PROXIMITY_NEGATIVE;
|
||||
mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_DEBOUNCE_DELAY;
|
||||
debounceProximitySensor();
|
||||
}
|
||||
|
||||
private void debounceProximitySensor() {
|
||||
if (mPendingProximity != PROXIMITY_UNKNOWN) {
|
||||
final long now = SystemClock.uptimeMillis();
|
||||
if (mPendingProximityDebounceTime <= now) {
|
||||
mProximity = mPendingProximity;
|
||||
sendUpdatePowerState();
|
||||
} else {
|
||||
Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setLightSensorEnabled(boolean enable) {
|
||||
if (enable) {
|
||||
if (!mLightSensorEnabled) {
|
||||
mLightSensorEnabled = true;
|
||||
mLightSensorEnableTime = SystemClock.uptimeMillis();
|
||||
mSensorManager.registerListener(mLightSensorListener, mLightSensor,
|
||||
LIGHT_SENSOR_RATE, mHandler);
|
||||
}
|
||||
} else {
|
||||
if (mLightSensorEnabled) {
|
||||
mLightSensorEnabled = false;
|
||||
mLightMeasurementValid = false;
|
||||
updateAutoBrightness(false);
|
||||
mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
|
||||
mSensorManager.unregisterListener(mLightSensorListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLightSensorEvent(long time, float lux) {
|
||||
// Take the first few readings during the warm-up period and apply them
|
||||
// immediately without debouncing.
|
||||
if (!mLightMeasurementValid
|
||||
|| (time - mLightSensorEnableTime) < mLightSensorWarmUpTimeConfig) {
|
||||
mLightMeasurement = lux;
|
||||
mLightMeasurementValid = true;
|
||||
mRecentLightSamples = 0;
|
||||
updateAutoBrightness(true);
|
||||
}
|
||||
|
||||
// Update our moving average.
|
||||
if (lux != mLightMeasurement && (mRecentLightSamples == 0
|
||||
|| (lux < mLightMeasurement && mRecentLightBrightening)
|
||||
|| (lux > mLightMeasurement && !mRecentLightBrightening))) {
|
||||
// If the newest light sample doesn't seem to be going in the
|
||||
// same general direction as recent samples, then start over.
|
||||
setRecentLight(time, lux, lux > mLightMeasurement);
|
||||
mPendingLightSensorDebounceTime = time + mRecentLightTimeConstant;
|
||||
} else if (mRecentLightSamples >= 1) {
|
||||
// Add the newest light sample to the moving average.
|
||||
accumulateRecentLight(time, lux);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "handleLightSensorEvent: lux=" + lux
|
||||
+ ", mLightMeasurementValid=" + mLightMeasurementValid
|
||||
+ ", mLightMeasurement=" + mLightMeasurement
|
||||
+ ", mRecentLightSamples=" + mRecentLightSamples
|
||||
+ ", mRecentLightAverage=" + mRecentLightAverage
|
||||
+ ", mRecentLightBrightening=" + mRecentLightBrightening
|
||||
+ ", mRecentLightTimeConstant=" + mRecentLightTimeConstant
|
||||
+ ", mPendingLightSensorDebounceTime="
|
||||
+ TimeUtils.formatUptime(mPendingLightSensorDebounceTime));
|
||||
}
|
||||
|
||||
// Debounce.
|
||||
mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
|
||||
debounceLightSensor();
|
||||
}
|
||||
|
||||
private void setRecentLight(long time, float lux, boolean brightening) {
|
||||
mRecentLightBrightening = brightening;
|
||||
mRecentLightTimeConstant = brightening ?
|
||||
BRIGHTENING_LIGHT_TIME_CONSTANT : DIMMING_LIGHT_TIME_CONSTANT;
|
||||
mRecentLightSamples = 1;
|
||||
mRecentLightAverage = lux;
|
||||
mLastLightSample = lux;
|
||||
mLastLightSampleTime = time;
|
||||
}
|
||||
|
||||
private void accumulateRecentLight(long time, float lux) {
|
||||
final long timeDelta = time - mLastLightSampleTime;
|
||||
mRecentLightSamples += 1;
|
||||
mRecentLightAverage += (lux - mRecentLightAverage) *
|
||||
timeDelta / (mRecentLightTimeConstant + timeDelta);
|
||||
mLastLightSample = lux;
|
||||
mLastLightSampleTime = time;
|
||||
}
|
||||
|
||||
private void debounceLightSensor() {
|
||||
if (mLightMeasurementValid && mRecentLightSamples >= 1) {
|
||||
final long now = SystemClock.uptimeMillis();
|
||||
if (mPendingLightSensorDebounceTime <= now) {
|
||||
accumulateRecentLight(now, mLastLightSample);
|
||||
mLightMeasurement = mRecentLightAverage;
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "debounceLightSensor: Accepted new measurement "
|
||||
+ mLightMeasurement + " after "
|
||||
+ (now - mPendingLightSensorDebounceTime
|
||||
+ mRecentLightTimeConstant) + " ms based on "
|
||||
+ mRecentLightSamples + " recent samples.");
|
||||
}
|
||||
|
||||
updateAutoBrightness(true);
|
||||
|
||||
// Now that we have debounced the light sensor data, we have the
|
||||
// option of either leaving the sensor in a debounced state or
|
||||
// restarting the debounce cycle by setting mRecentLightSamples to 0.
|
||||
//
|
||||
// If we leave the sensor debounced, then new average light measurements
|
||||
// may be accepted immediately as long as they are trending in the same
|
||||
// direction as they were before. If the measurements start
|
||||
// jittering or trending in the opposite direction then the debounce
|
||||
// cycle will automatically be restarted. The benefit is that the
|
||||
// auto-brightness control can be more responsive to changes over a
|
||||
// broad range.
|
||||
//
|
||||
// For now, we choose to be more responsive and leave the following line
|
||||
// commented out.
|
||||
//
|
||||
// mRecentLightSamples = 0;
|
||||
} else {
|
||||
Message msg = mHandler.obtainMessage(MSG_LIGHT_SENSOR_DEBOUNCED);
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessageAtTime(msg, mPendingLightSensorDebounceTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAutoBrightness(boolean sendUpdate) {
|
||||
if (!mLightMeasurementValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int newScreenAutoBrightness = mapLuxToBrightness(mLightMeasurement,
|
||||
mAutoBrightnessLevelsConfig,
|
||||
mAutoBrightnessLcdBacklightValuesConfig);
|
||||
if (mScreenAutoBrightness != newScreenAutoBrightness) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
|
||||
+ mScreenAutoBrightness);
|
||||
}
|
||||
|
||||
mScreenAutoBrightness = newScreenAutoBrightness;
|
||||
if (sendUpdate) {
|
||||
sendUpdatePowerState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a light sensor measurement in lux to a brightness value given
|
||||
* a table of lux breakpoint values and a table of brightnesses that
|
||||
* is one element larger.
|
||||
*/
|
||||
private static int mapLuxToBrightness(float lux,
|
||||
int[] fromLux, int[] toBrightness) {
|
||||
// TODO implement interpolation and possibly range expansion
|
||||
int level = 0;
|
||||
final int count = fromLux.length;
|
||||
while (level < count && lux >= fromLux[level]) {
|
||||
level += 1;
|
||||
}
|
||||
return toBrightness[level];
|
||||
}
|
||||
|
||||
private void sendOnStateChanged() {
|
||||
mCallbackHandler.post(mOnStateChangedRunnable);
|
||||
}
|
||||
|
||||
private final Runnable mOnStateChangedRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mCallbacks.onStateChanged();
|
||||
}
|
||||
};
|
||||
|
||||
private void sendOnProximityNegative() {
|
||||
mCallbackHandler.post(mOnProximityNegativeRunnable);
|
||||
}
|
||||
|
||||
private final Runnable mOnProximityNegativeRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mCallbacks.onProximityNegative();
|
||||
}
|
||||
};
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
synchronized (mLock) {
|
||||
pw.println();
|
||||
pw.println("Display Controller Locked State:");
|
||||
pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
|
||||
pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
|
||||
pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
|
||||
pw.println(" mPendingWaitForNegativeProximityLocked="
|
||||
+ mPendingWaitForNegativeProximityLocked);
|
||||
pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
|
||||
}
|
||||
|
||||
pw.println();
|
||||
pw.println("Display Controller Configuration:");
|
||||
pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
|
||||
pw.println(" mUseSoftwareAutoBrightnessConfig="
|
||||
+ mUseSoftwareAutoBrightnessConfig);
|
||||
pw.println(" mAutoBrightnessLevelsConfig="
|
||||
+ Arrays.toString(mAutoBrightnessLevelsConfig));
|
||||
pw.println(" mAutoBrightnessLcdBacklightValuesConfig="
|
||||
+ Arrays.toString(mAutoBrightnessLcdBacklightValuesConfig));
|
||||
pw.println(" mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
|
||||
|
||||
if (Looper.myLooper() == mHandler.getLooper()) {
|
||||
dumpLocal(pw);
|
||||
} else {
|
||||
final StringWriter out = new StringWriter();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Message msg = Message.obtain(mHandler, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PrintWriter localpw = new PrintWriter(out);
|
||||
try {
|
||||
dumpLocal(localpw);
|
||||
} finally {
|
||||
localpw.flush();
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
});
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessage(msg);
|
||||
try {
|
||||
latch.await();
|
||||
pw.print(out.toString());
|
||||
} catch (InterruptedException ex) {
|
||||
pw.println();
|
||||
pw.println("Failed to dump thread state due to interrupted exception!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpLocal(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("Display Controller Thread State:");
|
||||
pw.println(" mPowerRequest=" + mPowerRequest);
|
||||
pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
|
||||
|
||||
pw.println(" mProximitySensor=" + mProximitySensor);
|
||||
pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
|
||||
pw.println(" mProximityThreshold=" + mProximityThreshold);
|
||||
pw.println(" mProximity=" + proximityToString(mProximity));
|
||||
pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
|
||||
pw.println(" mPendingProximityDebounceTime="
|
||||
+ TimeUtils.formatUptime(mPendingProximityDebounceTime));
|
||||
pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
|
||||
|
||||
pw.println(" mLightSensor=" + mLightSensor);
|
||||
pw.println(" mLightSensorEnabled=" + mLightSensorEnabled);
|
||||
pw.println(" mLightSensorEnableTime="
|
||||
+ TimeUtils.formatUptime(mLightSensorEnableTime));
|
||||
pw.println(" mLightMeasurement=" + mLightMeasurement);
|
||||
pw.println(" mLightMeasurementValid=" + mLightMeasurementValid);
|
||||
pw.println(" mLastLightSample=" + mLastLightSample);
|
||||
pw.println(" mLastLightSampleTime="
|
||||
+ TimeUtils.formatUptime(mLastLightSampleTime));
|
||||
pw.println(" mRecentLightSamples=" + mRecentLightSamples);
|
||||
pw.println(" mRecentLightAverage=" + mRecentLightAverage);
|
||||
pw.println(" mRecentLightBrightening=" + mRecentLightBrightening);
|
||||
pw.println(" mRecentLightTimeConstant=" + mRecentLightTimeConstant);
|
||||
pw.println(" mPendingLightSensorDebounceTime="
|
||||
+ TimeUtils.formatUptime(mPendingLightSensorDebounceTime));
|
||||
pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness);
|
||||
pw.println(" mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness);
|
||||
|
||||
if (mElectronBeamOnAnimator != null) {
|
||||
pw.println(" mElectronBeamOnAnimator.isStarted()=" +
|
||||
mElectronBeamOnAnimator.isStarted());
|
||||
}
|
||||
if (mElectronBeamOffAnimator != null) {
|
||||
pw.println(" mElectronBeamOffAnimator.isStarted()=" +
|
||||
mElectronBeamOffAnimator.isStarted());
|
||||
}
|
||||
|
||||
if (mPowerState != null) {
|
||||
mPowerState.dump(pw);
|
||||
}
|
||||
}
|
||||
|
||||
private static String proximityToString(int state) {
|
||||
switch (state) {
|
||||
case PROXIMITY_UNKNOWN:
|
||||
return "Unknown";
|
||||
case PROXIMITY_NEGATIVE:
|
||||
return "Negative";
|
||||
case PROXIMITY_POSITIVE:
|
||||
return "Positive";
|
||||
default:
|
||||
return Integer.toString(state);
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
public interface Callbacks {
|
||||
void onStateChanged();
|
||||
void onProximityNegative();
|
||||
}
|
||||
|
||||
private final class DisplayControllerHandler extends Handler {
|
||||
public DisplayControllerHandler(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_UPDATE_POWER_STATE:
|
||||
updatePowerState();
|
||||
break;
|
||||
|
||||
case MSG_PROXIMITY_SENSOR_DEBOUNCED:
|
||||
debounceProximitySensor();
|
||||
break;
|
||||
|
||||
case MSG_LIGHT_SENSOR_DEBOUNCED:
|
||||
debounceLightSensor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (mProximitySensorEnabled) {
|
||||
final long time = SystemClock.uptimeMillis();
|
||||
final float distance = event.values[0];
|
||||
boolean positive = distance >= 0.0f && distance < mProximityThreshold;
|
||||
handleProximitySensorEvent(time, positive);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// Not used.
|
||||
}
|
||||
};
|
||||
|
||||
private final SensorEventListener mLightSensorListener = new SensorEventListener() {
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (mLightSensorEnabled) {
|
||||
final long time = SystemClock.uptimeMillis();
|
||||
final float lux = event.values[0];
|
||||
handleLightSensorEvent(time, lux);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// Not used.
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.power;
|
||||
|
||||
import android.os.PowerManager;
|
||||
|
||||
/**
|
||||
* Describes the requested power state of the display.
|
||||
*
|
||||
* This object is intended to describe the general characteristics of the
|
||||
* power state, such as whether the screen should be on or off and the current
|
||||
* brightness controls leaving the {@link DisplayPowerController} to manage the
|
||||
* details of how the transitions between states should occur. The goal is for
|
||||
* the {@link PowerManagerService} to focus on the global power state and not
|
||||
* have to micro-manage screen off animations, auto-brightness and other effects.
|
||||
*/
|
||||
final class DisplayPowerRequest {
|
||||
public static final int SCREEN_STATE_OFF = 0;
|
||||
public static final int SCREEN_STATE_DIM = 1;
|
||||
public static final int SCREEN_STATE_BRIGHT = 2;
|
||||
|
||||
// The requested minimum screen power state: off, dim or bright.
|
||||
public int screenState;
|
||||
|
||||
// If true, the proximity sensor overrides the screen state when an object is
|
||||
// nearby, turning it off temporarily until the object is moved away.
|
||||
public boolean useProximitySensor;
|
||||
|
||||
// The desired screen brightness in the range 0 (minimum / off) to 255 (brightest).
|
||||
// The display power controller may choose to clamp the brightness.
|
||||
// When auto-brightness is enabled, this field should specify a nominal default
|
||||
// value to use while waiting for the light sensor to report enough data.
|
||||
public int screenBrightness;
|
||||
|
||||
// If true, enables automatic brightness control.
|
||||
public boolean useAutoBrightness;
|
||||
|
||||
public DisplayPowerRequest() {
|
||||
screenState = SCREEN_STATE_BRIGHT;
|
||||
useProximitySensor = false;
|
||||
screenBrightness = PowerManager.BRIGHTNESS_ON;
|
||||
useAutoBrightness = false;
|
||||
}
|
||||
|
||||
public DisplayPowerRequest(DisplayPowerRequest other) {
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
public void copyFrom(DisplayPowerRequest other) {
|
||||
screenState = other.screenState;
|
||||
useProximitySensor = other.useProximitySensor;
|
||||
screenBrightness = other.screenBrightness;
|
||||
useAutoBrightness = other.useAutoBrightness;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof DisplayPowerRequest
|
||||
&& equals((DisplayPowerRequest)o);
|
||||
}
|
||||
|
||||
public boolean equals(DisplayPowerRequest other) {
|
||||
return other != null
|
||||
&& screenState == other.screenState
|
||||
&& useProximitySensor == other.useProximitySensor
|
||||
&& screenBrightness == other.screenBrightness
|
||||
&& useAutoBrightness == other.useAutoBrightness;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0; // don't care
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "screenState=" + screenState
|
||||
+ ", useProximitySensor=" + useProximitySensor
|
||||
+ ", screenBrightness=" + screenBrightness
|
||||
+ ", useAutoBrightness=" + useAutoBrightness;
|
||||
}
|
||||
}
|
||||
269
services/java/com/android/server/power/DisplayPowerState.java
Normal file
269
services/java/com/android/server/power/DisplayPowerState.java
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.power;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.os.PowerManager;
|
||||
import android.util.FloatProperty;
|
||||
import android.util.IntProperty;
|
||||
import android.util.Slog;
|
||||
import android.view.Choreographer;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Represents the current display power state and realizes it.
|
||||
*
|
||||
* This component is similar in nature to a {@link View} except that it describes
|
||||
* the properties of a display. When properties are changed, the component
|
||||
* invalidates itself and posts a callback to the {@link Choreographer} to
|
||||
* apply the changes. This mechanism enables the display power state to be
|
||||
* animated smoothly by the animation framework.
|
||||
*
|
||||
* This component must only be created or accessed by the {@link Looper} thread
|
||||
* that belongs to the {@link DisplayPowerController}.
|
||||
*
|
||||
* We don't need to worry about holding a suspend blocker here because the
|
||||
* {@link DisplayPowerController} does that for us whenever there is a pending invalidate.
|
||||
*/
|
||||
final class DisplayPowerState {
|
||||
private static final String TAG = "DisplayPowerState";
|
||||
|
||||
private static boolean DEBUG = false;
|
||||
|
||||
private static final int DIRTY_SCREEN_ON = 1 << 0;
|
||||
private static final int DIRTY_ELECTRON_BEAM = 1 << 1;
|
||||
private static final int DIRTY_BRIGHTNESS = 1 << 2;
|
||||
|
||||
private static final int DIRTY_ALL = 0xffffffff;
|
||||
|
||||
private final Choreographer mChoreographer;
|
||||
private final ElectronBeam mElectronBeam;
|
||||
private final PhotonicModulator mScreenBrightnessModulator;
|
||||
|
||||
private int mDirty;
|
||||
private boolean mScreenOn;
|
||||
private float mElectronBeamLevel;
|
||||
private int mScreenBrightness;
|
||||
|
||||
private Runnable mCleanListener;
|
||||
|
||||
public DisplayPowerState(ElectronBeam electronBean,
|
||||
PhotonicModulator screenBrightnessModulator) {
|
||||
mChoreographer = Choreographer.getInstance();
|
||||
mElectronBeam = electronBean;
|
||||
mScreenBrightnessModulator = screenBrightnessModulator;
|
||||
|
||||
mScreenOn = true;
|
||||
mElectronBeamLevel = 1.0f;
|
||||
mScreenBrightness = PowerManager.BRIGHTNESS_ON;
|
||||
invalidate(DIRTY_ALL);
|
||||
}
|
||||
|
||||
public static final FloatProperty<DisplayPowerState> ELECTRON_BEAM_LEVEL =
|
||||
new FloatProperty<DisplayPowerState>("electronBeamLevel") {
|
||||
@Override
|
||||
public void setValue(DisplayPowerState object, float value) {
|
||||
object.setElectronBeamLevel(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(DisplayPowerState object) {
|
||||
return object.getElectronBeamLevel();
|
||||
}
|
||||
};
|
||||
|
||||
public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS =
|
||||
new IntProperty<DisplayPowerState>("screenBrightness") {
|
||||
@Override
|
||||
public void setValue(DisplayPowerState object, int value) {
|
||||
object.setScreenBrightness(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer get(DisplayPowerState object) {
|
||||
return object.getScreenBrightness();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets whether the screen is on or off.
|
||||
*/
|
||||
public void setScreenOn(boolean on) {
|
||||
if (mScreenOn != on) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setScreenOn: on=" + on);
|
||||
}
|
||||
|
||||
mScreenOn = on;
|
||||
invalidate(DIRTY_SCREEN_ON);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the screen is on.
|
||||
*/
|
||||
public boolean isScreenOn() {
|
||||
return mScreenOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the electron beam to turn on or off.
|
||||
* This method should be called before starting an animation because it
|
||||
* can take a fair amount of time to prepare the electron beam surface.
|
||||
*
|
||||
* @param warmUp True if the electron beam should start warming up.
|
||||
* @return True if the electron beam was prepared.
|
||||
*/
|
||||
public boolean prepareElectronBeam(boolean warmUp) {
|
||||
boolean success = mElectronBeam.prepare(warmUp);
|
||||
invalidate(DIRTY_ELECTRON_BEAM);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses the electron beam surface.
|
||||
*/
|
||||
public void dismissElectronBeam() {
|
||||
mElectronBeam.dismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the level of the electron beam steering current.
|
||||
*
|
||||
* The display is blanked when the level is 0.0. In normal use, the electron
|
||||
* beam should have a value of 1.0. The electron beam is unstable in between
|
||||
* these states and the picture quality may be compromised. For best effect,
|
||||
* the electron beam should be warmed up or cooled off slowly.
|
||||
*
|
||||
* Warning: Electron beam emits harmful radiation. Avoid direct exposure to
|
||||
* skin or eyes.
|
||||
*
|
||||
* @param level The level, ranges from 0.0 (full off) to 1.0 (full on).
|
||||
*/
|
||||
public void setElectronBeamLevel(float level) {
|
||||
if (mElectronBeamLevel != level) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setElectronBeamLevel: level=" + level);
|
||||
}
|
||||
|
||||
mElectronBeamLevel = level;
|
||||
invalidate(DIRTY_ELECTRON_BEAM);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level of the electron beam steering current.
|
||||
*/
|
||||
public float getElectronBeamLevel() {
|
||||
return mElectronBeamLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the display brightness.
|
||||
*
|
||||
* @param brightness The brightness, ranges from 0 (minimum / off) to 255 (brightest).
|
||||
*/
|
||||
public void setScreenBrightness(int brightness) {
|
||||
if (mScreenBrightness != brightness) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
|
||||
}
|
||||
|
||||
mScreenBrightness = brightness;
|
||||
invalidate(DIRTY_BRIGHTNESS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the screen brightness.
|
||||
*/
|
||||
public int getScreenBrightness() {
|
||||
return mScreenBrightness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if no properties have been invalidated.
|
||||
* Otherwise, returns false and promises to invoke the specified listener
|
||||
* when the properties have all been applied.
|
||||
* The listener always overrides any previously set listener.
|
||||
*/
|
||||
public boolean waitUntilClean(Runnable listener) {
|
||||
if (mDirty != 0) {
|
||||
mCleanListener = listener;
|
||||
return false;
|
||||
} else {
|
||||
mCleanListener = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("Display Power State:");
|
||||
pw.println(" mDirty=" + Integer.toHexString(mDirty));
|
||||
pw.println(" mScreenOn=" + mScreenOn);
|
||||
pw.println(" mScreenBrightness=" + mScreenBrightness);
|
||||
pw.println(" mElectronBeamLevel=" + mElectronBeamLevel);
|
||||
|
||||
mElectronBeam.dump(pw);
|
||||
}
|
||||
|
||||
private void invalidate(int dirty) {
|
||||
if (mDirty == 0) {
|
||||
mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL,
|
||||
mTraversalRunnable, null);
|
||||
}
|
||||
|
||||
mDirty |= dirty;
|
||||
}
|
||||
|
||||
private void apply() {
|
||||
if (mDirty != 0) {
|
||||
if ((mDirty & DIRTY_SCREEN_ON) != 0 && !mScreenOn) {
|
||||
PowerManagerService.nativeSetScreenState(false);
|
||||
}
|
||||
|
||||
if ((mDirty & DIRTY_ELECTRON_BEAM) != 0) {
|
||||
mElectronBeam.draw(mElectronBeamLevel);
|
||||
}
|
||||
|
||||
if ((mDirty & DIRTY_BRIGHTNESS) != 0) {
|
||||
mScreenBrightnessModulator.setBrightness(mScreenBrightness);
|
||||
}
|
||||
|
||||
if ((mDirty & DIRTY_SCREEN_ON) != 0 && mScreenOn) {
|
||||
PowerManagerService.nativeSetScreenState(true);
|
||||
}
|
||||
|
||||
mDirty = 0;
|
||||
|
||||
if (mCleanListener != null) {
|
||||
mCleanListener.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable mTraversalRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mDirty != 0) {
|
||||
apply();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
652
services/java/com/android/server/power/ElectronBeam.java
Normal file
652
services/java/com/android/server/power/ElectronBeam.java
Normal file
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.power;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.opengl.EGL14;
|
||||
import android.opengl.EGLConfig;
|
||||
import android.opengl.EGLContext;
|
||||
import android.opengl.EGLDisplay;
|
||||
import android.opengl.EGLSurface;
|
||||
import android.opengl.GLES10;
|
||||
import android.opengl.GLUtils;
|
||||
import android.os.Looper;
|
||||
import android.os.Process;
|
||||
import android.util.FloatMath;
|
||||
import android.util.Slog;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceSession;
|
||||
import android.view.WindowManagerImpl;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
/**
|
||||
* Bzzzoooop! *crackle*
|
||||
*
|
||||
* Animates a screen transition from on to off or off to on by applying
|
||||
* some GL transformations to a screenshot.
|
||||
*
|
||||
* This component must only be created or accessed by the {@link Looper} thread
|
||||
* that belongs to the {@link DisplayPowerController}.
|
||||
*/
|
||||
final class ElectronBeam {
|
||||
private static final String TAG = "ElectronBeam";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
// The layer for the electron beam surface.
|
||||
// This is currently hardcoded to be one layer above the boot animation.
|
||||
private static final int ELECTRON_BEAM_LAYER = 0x40000001;
|
||||
|
||||
// The relative proportion of the animation to spend performing
|
||||
// the horizontal stretch effect. The remainder is spent performing
|
||||
// the vertical stretch effect.
|
||||
private static final float HSTRETCH_DURATION = 0.3f;
|
||||
private static final float VSTRETCH_DURATION = 1.0f - HSTRETCH_DURATION;
|
||||
|
||||
// Set to true when the animation context has been fully prepared.
|
||||
private boolean mPrepared;
|
||||
private boolean mWarmUp;
|
||||
|
||||
private final DisplayInfo mDisplayInfo = new DisplayInfo();
|
||||
private int mDisplayLayerStack; // layer stack associated with primary display
|
||||
private int mDisplayRotation;
|
||||
private int mDisplayWidth; // real width, not rotated
|
||||
private int mDisplayHeight; // real height, not rotated
|
||||
private SurfaceSession mSurfaceSession;
|
||||
private Surface mSurface;
|
||||
private EGLDisplay mEglDisplay;
|
||||
private EGLConfig mEglConfig;
|
||||
private EGLContext mEglContext;
|
||||
private EGLSurface mEglSurface;
|
||||
private boolean mSurfaceVisible;
|
||||
|
||||
// Texture names. We only use one texture, which contains the screenshot.
|
||||
private final int[] mTexNames = new int[1];
|
||||
private boolean mTexNamesGenerated;
|
||||
|
||||
// Vertex and corresponding texture coordinates.
|
||||
// We have 4 2D vertices, so 8 elements. The vertices form a quad.
|
||||
private final FloatBuffer mVertexBuffer = createNativeFloatBuffer(8);
|
||||
private final FloatBuffer mTexCoordBuffer = createNativeFloatBuffer(8);
|
||||
|
||||
public ElectronBeam() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Warms up the electron beam in preparation for turning on or off.
|
||||
* This method prepares a GL context, and captures a screen shot.
|
||||
*
|
||||
* @param warmUp True if the electron beam is about to be turned on, false if
|
||||
* it is about to be turned off.
|
||||
* @return True if the electron beam is ready, false if it is uncontrollable.
|
||||
*/
|
||||
public boolean prepare(boolean warmUp) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "prepare: warmUp=" + warmUp);
|
||||
}
|
||||
|
||||
mWarmUp = warmUp;
|
||||
|
||||
// Get the display size and adjust it for rotation.
|
||||
Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
|
||||
display.getDisplayInfo(mDisplayInfo);
|
||||
mDisplayLayerStack = display.getDisplayId();
|
||||
mDisplayRotation = mDisplayInfo.rotation;
|
||||
if (mDisplayRotation == Surface.ROTATION_90
|
||||
|| mDisplayRotation == Surface.ROTATION_270) {
|
||||
mDisplayWidth = mDisplayInfo.logicalHeight;
|
||||
mDisplayHeight = mDisplayInfo.logicalWidth;
|
||||
} else {
|
||||
mDisplayWidth = mDisplayInfo.logicalWidth;
|
||||
mDisplayHeight = mDisplayInfo.logicalHeight;
|
||||
}
|
||||
|
||||
// Prepare the surface for drawing.
|
||||
if (!createEglContext()
|
||||
|| !createEglSurface()
|
||||
|| !captureScreenshotTextureAndSetViewport()) {
|
||||
dismiss();
|
||||
return false;
|
||||
}
|
||||
|
||||
mPrepared = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses the electron beam animation surface and cleans up.
|
||||
*
|
||||
* To prevent stray photons from leaking out after the electron beam has been
|
||||
* turned off, it is a good idea to defer dismissing the animation until the
|
||||
* electron beam has been turned back on fully.
|
||||
*/
|
||||
public void dismiss() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "dismiss");
|
||||
}
|
||||
|
||||
destroyScreenshotTexture();
|
||||
destroyEglSurface();
|
||||
mPrepared = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an animation frame showing the electron beam activated at the
|
||||
* specified level.
|
||||
*
|
||||
* @param level The electron beam level.
|
||||
* @return True if successful.
|
||||
*/
|
||||
public boolean draw(float level) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "drawFrame: level=" + level);
|
||||
}
|
||||
|
||||
if (!attachEglContext()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
// Clear frame to solid black.
|
||||
GLES10.glClearColor(0f, 0f, 0f, 1f);
|
||||
GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Draw the frame.
|
||||
if (level < HSTRETCH_DURATION) {
|
||||
drawHStretch(1.0f - (level / HSTRETCH_DURATION));
|
||||
} else {
|
||||
drawVStretch(1.0f - ((level - HSTRETCH_DURATION) / VSTRETCH_DURATION));
|
||||
}
|
||||
if (checkGlErrors("drawFrame")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EGL14.eglSwapBuffers(mEglDisplay, mEglSurface);
|
||||
} finally {
|
||||
detachEglContext();
|
||||
}
|
||||
|
||||
return showEglSurface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a frame where the content of the electron beam is collapsing inwards upon
|
||||
* itself vertically with red / green / blue channels dispersing and eventually
|
||||
* merging down to a single horizontal line.
|
||||
*
|
||||
* @param stretch The stretch factor. 0.0 is no collapse, 1.0 is full collapse.
|
||||
*/
|
||||
private void drawVStretch(float stretch) {
|
||||
// compute interpolation scale factors for each color channel
|
||||
final float ar = scurve(stretch, 7.5f);
|
||||
final float ag = scurve(stretch, 8.0f);
|
||||
final float ab = scurve(stretch, 8.5f);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "drawVStretch: stretch=" + stretch
|
||||
+ ", ar=" + ar + ", ag=" + ag + ", ab=" + ab);
|
||||
}
|
||||
|
||||
// set blending
|
||||
GLES10.glBlendFunc(GLES10.GL_ONE, GLES10.GL_ONE);
|
||||
GLES10.glEnable(GLES10.GL_BLEND);
|
||||
|
||||
// bind vertex buffer
|
||||
GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer);
|
||||
GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
|
||||
|
||||
// bind texture and set blending for drawing planes
|
||||
GLES10.glBindTexture(GLES10.GL_TEXTURE_2D, mTexNames[0]);
|
||||
GLES10.glTexEnvx(GLES10.GL_TEXTURE_ENV, GLES10.GL_TEXTURE_ENV_MODE,
|
||||
mWarmUp ? GLES10.GL_MODULATE : GLES10.GL_REPLACE);
|
||||
GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
|
||||
GLES10.GL_TEXTURE_MAG_FILTER, GLES10.GL_LINEAR);
|
||||
GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
|
||||
GLES10.GL_TEXTURE_MIN_FILTER, GLES10.GL_LINEAR);
|
||||
GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
|
||||
GLES10.GL_TEXTURE_WRAP_S, GLES10.GL_CLAMP_TO_EDGE);
|
||||
GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
|
||||
GLES10.GL_TEXTURE_WRAP_T, GLES10.GL_CLAMP_TO_EDGE);
|
||||
GLES10.glEnable(GLES10.GL_TEXTURE_2D);
|
||||
GLES10.glTexCoordPointer(2, GLES10.GL_FLOAT, 0, mTexCoordBuffer);
|
||||
GLES10.glEnableClientState(GLES10.GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
// draw the red plane
|
||||
setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ar);
|
||||
GLES10.glColorMask(true, false, false, true);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// draw the green plane
|
||||
setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag);
|
||||
GLES10.glColorMask(false, true, false, true);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// draw the blue plane
|
||||
setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ab);
|
||||
GLES10.glColorMask(false, false, true, true);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// clean up after drawing planes
|
||||
GLES10.glDisable(GLES10.GL_TEXTURE_2D);
|
||||
GLES10.glDisableClientState(GLES10.GL_TEXTURE_COORD_ARRAY);
|
||||
GLES10.glColorMask(true, true, true, true);
|
||||
|
||||
// draw the white highlight (we use the last vertices)
|
||||
if (!mWarmUp) {
|
||||
GLES10.glColor4f(ag, ag, ag, 1.0f);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
// clean up
|
||||
GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY);
|
||||
GLES10.glDisable(GLES10.GL_BLEND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a frame where the electron beam has been stretched out into
|
||||
* a thin white horizontal line that fades as it expands outwards.
|
||||
*
|
||||
* @param stretch The stretch factor. 0.0 is no stretch / no fade,
|
||||
* 1.0 is maximum stretch / maximum fade.
|
||||
*/
|
||||
private void drawHStretch(float stretch) {
|
||||
// compute interpolation scale factor
|
||||
final float ag = scurve(stretch, 8.0f);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "drawHStretch: stretch=" + stretch + ", ag=" + ag);
|
||||
}
|
||||
|
||||
if (stretch < 1.0f) {
|
||||
// bind vertex buffer
|
||||
GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer);
|
||||
GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
|
||||
|
||||
// draw narrow fading white line
|
||||
setHStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag);
|
||||
GLES10.glColor4f(1.0f - ag, 1.0f - ag, 1.0f - ag, 1.0f);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// clean up
|
||||
GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setVStretchQuad(FloatBuffer vtx, float dw, float dh, float a) {
|
||||
final float w = dw + (dw * a);
|
||||
final float h = dh - (dh * a);
|
||||
final float x = (dw - w) * 0.5f;
|
||||
final float y = (dh - h) * 0.5f;
|
||||
setQuad(vtx, x, y, w, h);
|
||||
}
|
||||
|
||||
private static void setHStretchQuad(FloatBuffer vtx, float dw, float dh, float a) {
|
||||
final float w = dw + (dw * a);
|
||||
final float h = 1.0f;
|
||||
final float x = (dw - w) * 0.5f;
|
||||
final float y = (dh - h) * 0.5f;
|
||||
setQuad(vtx, x, y, w, h);
|
||||
}
|
||||
|
||||
private static void setQuad(FloatBuffer vtx, float x, float y, float w, float h) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setQuad: x=" + x + ", y=" + y + ", w=" + w + ", h=" + h);
|
||||
}
|
||||
vtx.put(0, x);
|
||||
vtx.put(1, y);
|
||||
vtx.put(2, x);
|
||||
vtx.put(3, y + h);
|
||||
vtx.put(4, x + w);
|
||||
vtx.put(5, y + h);
|
||||
vtx.put(6, x + w);
|
||||
vtx.put(7, y);
|
||||
}
|
||||
|
||||
private boolean captureScreenshotTextureAndSetViewport() {
|
||||
// TODO: Use a SurfaceTexture to avoid the extra texture upload.
|
||||
Bitmap bitmap = Surface.screenshot(mDisplayWidth, mDisplayHeight,
|
||||
0, ELECTRON_BEAM_LAYER - 1);
|
||||
if (bitmap == null) {
|
||||
Slog.e(TAG, "Could not take a screenshot!");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (!attachEglContext()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (!mTexNamesGenerated) {
|
||||
GLES10.glGenTextures(1, mTexNames, 0);
|
||||
if (checkGlErrors("glGenTextures")) {
|
||||
return false;
|
||||
}
|
||||
mTexNamesGenerated = true;
|
||||
}
|
||||
|
||||
GLES10.glBindTexture(GLES10.GL_TEXTURE_2D, mTexNames[0]);
|
||||
if (checkGlErrors("glBindTexture")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float u = 1.0f;
|
||||
float v = 1.0f;
|
||||
GLUtils.texImage2D(GLES10.GL_TEXTURE_2D, 0, bitmap, 0);
|
||||
if (checkGlErrors("glTexImage2D, first try", false)) {
|
||||
// Try a power of two size texture instead.
|
||||
int tw = nextPowerOfTwo(mDisplayWidth);
|
||||
int th = nextPowerOfTwo(mDisplayHeight);
|
||||
int format = GLUtils.getInternalFormat(bitmap);
|
||||
GLES10.glTexImage2D(GLES10.GL_TEXTURE_2D, 0,
|
||||
format, tw, th, 0,
|
||||
format, GLES10.GL_UNSIGNED_BYTE, null);
|
||||
if (checkGlErrors("glTexImage2D, second try")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GLUtils.texSubImage2D(GLES10.GL_TEXTURE_2D, 0, 0, 0, bitmap);
|
||||
if (checkGlErrors("glTexSubImage2D")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u = (float)mDisplayWidth / tw;
|
||||
v = (float)mDisplayHeight / th;
|
||||
}
|
||||
|
||||
// Set up texture coordinates for a quad.
|
||||
// We might need to change this if the texture ends up being
|
||||
// a different size from the display for some reason.
|
||||
mTexCoordBuffer.put(0, 0f);
|
||||
mTexCoordBuffer.put(1, v);
|
||||
mTexCoordBuffer.put(2, 0f);
|
||||
mTexCoordBuffer.put(3, 0f);
|
||||
mTexCoordBuffer.put(4, u);
|
||||
mTexCoordBuffer.put(5, 0f);
|
||||
mTexCoordBuffer.put(6, u);
|
||||
mTexCoordBuffer.put(7, v);
|
||||
|
||||
// Set up our viewport.
|
||||
GLES10.glViewport(0, 0, mDisplayWidth, mDisplayHeight);
|
||||
GLES10.glMatrixMode(GLES10.GL_PROJECTION);
|
||||
GLES10.glLoadIdentity();
|
||||
GLES10.glOrthof(0, mDisplayWidth, 0, mDisplayHeight, 0, 1);
|
||||
GLES10.glMatrixMode(GLES10.GL_MODELVIEW);
|
||||
GLES10.glLoadIdentity();
|
||||
GLES10.glMatrixMode(GLES10.GL_TEXTURE);
|
||||
GLES10.glLoadIdentity();
|
||||
} finally {
|
||||
detachEglContext();
|
||||
}
|
||||
} finally {
|
||||
bitmap.recycle();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void destroyScreenshotTexture() {
|
||||
if (mTexNamesGenerated) {
|
||||
mTexNamesGenerated = false;
|
||||
if (attachEglContext()) {
|
||||
try {
|
||||
GLES10.glDeleteTextures(1, mTexNames, 0);
|
||||
checkGlErrors("glDeleteTextures");
|
||||
} finally {
|
||||
detachEglContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean createEglContext() {
|
||||
if (mEglDisplay == null) {
|
||||
mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
|
||||
if (mEglDisplay == EGL14.EGL_NO_DISPLAY) {
|
||||
logEglError("eglGetDisplay");
|
||||
return false;
|
||||
}
|
||||
|
||||
int[] version = new int[2];
|
||||
if (!EGL14.eglInitialize(mEglDisplay, version, 0, version, 1)) {
|
||||
mEglDisplay = null;
|
||||
logEglError("eglInitialize");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mEglConfig == null) {
|
||||
int[] eglConfigAttribList = new int[] {
|
||||
EGL14.EGL_RED_SIZE, 8,
|
||||
EGL14.EGL_GREEN_SIZE, 8,
|
||||
EGL14.EGL_BLUE_SIZE, 8,
|
||||
EGL14.EGL_ALPHA_SIZE, 8,
|
||||
EGL14.EGL_NONE
|
||||
};
|
||||
int[] numEglConfigs = new int[1];
|
||||
EGLConfig[] eglConfigs = new EGLConfig[1];
|
||||
if (!EGL14.eglChooseConfig(mEglDisplay, eglConfigAttribList, 0,
|
||||
eglConfigs, 0, eglConfigs.length, numEglConfigs, 0)) {
|
||||
logEglError("eglChooseConfig");
|
||||
return false;
|
||||
}
|
||||
mEglConfig = eglConfigs[0];
|
||||
}
|
||||
|
||||
if (mEglContext == null) {
|
||||
int[] eglContextAttribList = new int[] {
|
||||
EGL14.EGL_NONE
|
||||
};
|
||||
mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig,
|
||||
EGL14.EGL_NO_CONTEXT, eglContextAttribList, 0);
|
||||
if (mEglContext == null) {
|
||||
logEglError("eglCreateContext");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* not used because it is too expensive to create / destroy contexts all of the time
|
||||
private void destroyEglContext() {
|
||||
if (mEglContext != null) {
|
||||
if (!EGL14.eglDestroyContext(mEglDisplay, mEglContext)) {
|
||||
logEglError("eglDestroyContext");
|
||||
}
|
||||
mEglContext = null;
|
||||
}
|
||||
}*/
|
||||
|
||||
private boolean createEglSurface() {
|
||||
if (mSurfaceSession == null) {
|
||||
mSurfaceSession = new SurfaceSession();
|
||||
}
|
||||
|
||||
Surface.openTransaction();
|
||||
try {
|
||||
if (mSurface == null) {
|
||||
try {
|
||||
mSurface = new Surface(mSurfaceSession, Process.myPid(),
|
||||
"ElectronBeam", mDisplayLayerStack, mDisplayWidth, mDisplayHeight,
|
||||
PixelFormat.OPAQUE, Surface.OPAQUE | Surface.HIDDEN);
|
||||
} catch (Surface.OutOfResourcesException ex) {
|
||||
Slog.e(TAG, "Unable to create surface.", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mSurface.setSize(mDisplayWidth, mDisplayHeight);
|
||||
|
||||
switch (mDisplayRotation) {
|
||||
case Surface.ROTATION_0:
|
||||
mSurface.setPosition(0, 0);
|
||||
mSurface.setMatrix(1, 0, 0, 1);
|
||||
break;
|
||||
case Surface.ROTATION_90:
|
||||
mSurface.setPosition(0, mDisplayWidth);
|
||||
mSurface.setMatrix(0, -1, 1, 0);
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
mSurface.setPosition(mDisplayWidth, mDisplayHeight);
|
||||
mSurface.setMatrix(-1, 0, 0, -1);
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
mSurface.setPosition(mDisplayHeight, 0);
|
||||
mSurface.setMatrix(0, 1, -1, 0);
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
Surface.closeTransaction();
|
||||
}
|
||||
|
||||
if (mEglSurface == null) {
|
||||
int[] eglSurfaceAttribList = new int[] {
|
||||
EGL14.EGL_NONE
|
||||
};
|
||||
mEglSurface = EGL14.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface,
|
||||
eglSurfaceAttribList, 0);
|
||||
if (mEglSurface == null) {
|
||||
logEglError("eglCreateWindowSurface");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void destroyEglSurface() {
|
||||
if (mEglSurface != null) {
|
||||
if (!EGL14.eglDestroySurface(mEglDisplay, mEglSurface)) {
|
||||
logEglError("eglDestroySurface");
|
||||
}
|
||||
mEglSurface = null;
|
||||
}
|
||||
|
||||
if (mSurface != null) {
|
||||
Surface.openTransaction();
|
||||
try {
|
||||
mSurface.destroy();
|
||||
} finally {
|
||||
Surface.closeTransaction();
|
||||
}
|
||||
mSurface = null;
|
||||
mSurfaceVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean showEglSurface() {
|
||||
if (!mSurfaceVisible) {
|
||||
Surface.openTransaction();
|
||||
try {
|
||||
mSurface.setLayer(ELECTRON_BEAM_LAYER);
|
||||
mSurface.show();
|
||||
} finally {
|
||||
Surface.closeTransaction();
|
||||
}
|
||||
mSurfaceVisible = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean attachEglContext() {
|
||||
if (mEglSurface == null) {
|
||||
return false;
|
||||
}
|
||||
if (!EGL14.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
||||
logEglError("eglMakeCurrent");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void detachEglContext() {
|
||||
if (mEglDisplay != null) {
|
||||
EGL14.eglMakeCurrent(mEglDisplay,
|
||||
EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolates a value in the range 0 .. 1 along a sigmoid curve
|
||||
* yielding a result in the range 0 .. 1 scaled such that:
|
||||
* scurve(0) == 0, scurve(0.5) == 0.5, scurve(1) == 1.
|
||||
*/
|
||||
private static float scurve(float value, float s) {
|
||||
// A basic sigmoid has the form y = 1.0f / FloatMap.exp(-x * s).
|
||||
// Here we take the input datum and shift it by 0.5 so that the
|
||||
// domain spans the range -0.5 .. 0.5 instead of 0 .. 1.
|
||||
final float x = value - 0.5f;
|
||||
|
||||
// Next apply the sigmoid function to the scaled value
|
||||
// which produces a value in the range 0 .. 1 so we subtract
|
||||
// 0.5 to get a value in the range -0.5 .. 0.5 instead.
|
||||
final float y = sigmoid(x, s) - 0.5f;
|
||||
|
||||
// To obtain the desired boundary conditions we need to scale
|
||||
// the result so that it fills a range of -1 .. 1.
|
||||
final float v = sigmoid(0.5f, s) - 0.5f;
|
||||
|
||||
// And finally remap the value back to a range of 0 .. 1.
|
||||
return y / v * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
private static float sigmoid(float x, float s) {
|
||||
return 1.0f / (1.0f + FloatMath.exp(-x * s));
|
||||
}
|
||||
|
||||
private static int nextPowerOfTwo(int value) {
|
||||
return 1 << (32 - Integer.numberOfLeadingZeros(value));
|
||||
}
|
||||
|
||||
private static FloatBuffer createNativeFloatBuffer(int size) {
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(size * 4);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
return bb.asFloatBuffer();
|
||||
}
|
||||
|
||||
private static void logEglError(String func) {
|
||||
Slog.e(TAG, func + " failed: error " + EGL14.eglGetError(), new Throwable());
|
||||
}
|
||||
|
||||
private static boolean checkGlErrors(String func) {
|
||||
return checkGlErrors(func, true);
|
||||
}
|
||||
|
||||
private static boolean checkGlErrors(String func, boolean log) {
|
||||
boolean hadError = false;
|
||||
int error;
|
||||
while ((error = GLES10.glGetError()) != GLES10.GL_NO_ERROR) {
|
||||
if (log) {
|
||||
Slog.e(TAG, func + " failed: error " + error, new Throwable());
|
||||
}
|
||||
hadError = true;
|
||||
}
|
||||
return hadError;
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("Electron Beam State:");
|
||||
pw.println(" mPrepared=" + mPrepared);
|
||||
pw.println(" mWarmUp=" + mWarmUp);
|
||||
pw.println(" mDisplayLayerStack=" + mDisplayLayerStack);
|
||||
pw.println(" mDisplayRotation=" + mDisplayRotation);
|
||||
pw.println(" mDisplayWidth=" + mDisplayWidth);
|
||||
pw.println(" mDisplayHeight=" + mDisplayHeight);
|
||||
pw.println(" mSurfaceVisible=" + mSurfaceVisible);
|
||||
}
|
||||
}
|
||||
458
services/java/com/android/server/power/Notifier.java
Normal file
458
services/java/com/android/server/power/Notifier.java
Normal file
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.power;
|
||||
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.server.EventLogTags;
|
||||
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.WorkSource;
|
||||
import android.util.EventLog;
|
||||
import android.util.Slog;
|
||||
import android.view.WindowManagerPolicy;
|
||||
import android.view.WindowManagerPolicy.ScreenOnListener;
|
||||
|
||||
/**
|
||||
* Sends broadcasts about important power state changes.
|
||||
*
|
||||
* This methods of this class may be called by the power manager service while
|
||||
* its lock is being held. Internally it takes care of sending broadcasts to
|
||||
* notify other components of the system or applications asynchronously.
|
||||
*
|
||||
* The notifier is designed to collapse unnecessary broadcasts when it is not
|
||||
* possible for the system to have observed an intermediate state.
|
||||
*
|
||||
* For example, if the device wakes up, goes to sleep and wakes up again immediately
|
||||
* before the go to sleep broadcast has been sent, then no broadcast will be
|
||||
* sent about the system going to sleep and waking up.
|
||||
*/
|
||||
final class Notifier {
|
||||
private static final String TAG = "PowerManagerNotifier";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static final int POWER_STATE_UNKNOWN = 0;
|
||||
private static final int POWER_STATE_AWAKE = 1;
|
||||
private static final int POWER_STATE_ASLEEP = 2;
|
||||
|
||||
private static final int MSG_USER_ACTIVITY = 1;
|
||||
private static final int MSG_BROADCAST = 2;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
private final Context mContext;
|
||||
private final IBatteryStats mBatteryStats;
|
||||
private final SuspendBlocker mSuspendBlocker;
|
||||
private final WindowManagerPolicy mPolicy;
|
||||
private final ScreenOnListener mScreenOnListener;
|
||||
|
||||
private final NotifierHandler mHandler;
|
||||
private final Intent mScreenOnIntent;
|
||||
private final Intent mScreenOffIntent;
|
||||
|
||||
// The current power state.
|
||||
private int mActualPowerState;
|
||||
private int mLastGoToSleepReason;
|
||||
|
||||
// The currently broadcasted power state. This reflects what other parts of the
|
||||
// system have observed.
|
||||
private int mBroadcastedPowerState;
|
||||
private boolean mBroadcastInProgress;
|
||||
private long mBroadcastStartTime;
|
||||
|
||||
// True if a user activity message should be sent.
|
||||
private boolean mUserActivityPending;
|
||||
|
||||
public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
|
||||
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
|
||||
ScreenOnListener screenOnListener) {
|
||||
mContext = context;
|
||||
mBatteryStats = batteryStats;
|
||||
mSuspendBlocker = suspendBlocker;
|
||||
mPolicy = policy;
|
||||
mScreenOnListener = screenOnListener;
|
||||
|
||||
mHandler = new NotifierHandler(looper);
|
||||
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
|
||||
mScreenOnIntent.addFlags(
|
||||
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
|
||||
mScreenOffIntent.addFlags(
|
||||
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a wake lock is acquired.
|
||||
*/
|
||||
public void onWakeLockAcquired(int flags, String tag, int ownerUid, int ownerPid,
|
||||
WorkSource workSource) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
|
||||
+ "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
|
||||
+ ", workSource=" + workSource);
|
||||
}
|
||||
|
||||
if (!isWakeLockAlreadyReportedToBatteryStats(tag, ownerUid)) {
|
||||
try {
|
||||
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
|
||||
if (workSource != null) {
|
||||
mBatteryStats.noteStartWakelockFromSource(
|
||||
workSource, ownerPid, tag, monitorType);
|
||||
} else {
|
||||
mBatteryStats.noteStartWakelock(
|
||||
ownerUid, ownerPid, tag, monitorType);
|
||||
}
|
||||
} catch (RemoteException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a wake lock is released.
|
||||
*/
|
||||
public void onWakeLockReleased(int flags, String tag, int ownerUid, int ownerPid,
|
||||
WorkSource workSource) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
|
||||
+ "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
|
||||
+ ", workSource=" + workSource);
|
||||
}
|
||||
|
||||
if (!isWakeLockAlreadyReportedToBatteryStats(tag, ownerUid)) {
|
||||
try {
|
||||
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
|
||||
if (workSource != null) {
|
||||
mBatteryStats.noteStopWakelockFromSource(
|
||||
workSource, ownerPid, tag, monitorType);
|
||||
} else {
|
||||
mBatteryStats.noteStopWakelock(
|
||||
ownerUid, ownerPid, tag, monitorType);
|
||||
}
|
||||
} catch (RemoteException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isWakeLockAlreadyReportedToBatteryStats(String tag, int uid) {
|
||||
// The window manager already takes care of reporting battery stats associated
|
||||
// with the use of the KEEP_SCREEN_ON_FLAG.
|
||||
// TODO: Use a WorkSource to handle this situation instead of hardcoding it here.
|
||||
return uid == Process.SYSTEM_UID
|
||||
&& tag.equals(PowerManager.KEEP_SCREEN_ON_FLAG_TAG);
|
||||
}
|
||||
|
||||
private static int getBatteryStatsWakeLockMonitorType(int flags) {
|
||||
switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
|
||||
case PowerManager.PARTIAL_WAKE_LOCK:
|
||||
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
|
||||
return BatteryStats.WAKE_TYPE_PARTIAL;
|
||||
default:
|
||||
return BatteryStats.WAKE_TYPE_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the screen is turned on.
|
||||
*/
|
||||
public void onScreenOn() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onScreenOn");
|
||||
}
|
||||
|
||||
try {
|
||||
mBatteryStats.noteScreenOn();
|
||||
} catch (RemoteException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the screen is turned off.
|
||||
*/
|
||||
public void onScreenOff() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onScreenOff");
|
||||
}
|
||||
|
||||
try {
|
||||
mBatteryStats.noteScreenOff();
|
||||
} catch (RemoteException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the screen changes brightness.
|
||||
*/
|
||||
public void onScreenBrightness(int brightness) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onScreenBrightness: brightness=" + brightness);
|
||||
}
|
||||
|
||||
try {
|
||||
mBatteryStats.noteScreenBrightness(brightness);
|
||||
} catch (RemoteException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the device is waking up from sleep and the
|
||||
* display is about to be turned on.
|
||||
*/
|
||||
public void onWakeUpStarted() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onWakeUpStarted");
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (mActualPowerState != POWER_STATE_AWAKE) {
|
||||
mActualPowerState = POWER_STATE_AWAKE;
|
||||
updatePendingBroadcastLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the device has finished waking up from sleep
|
||||
* and the display has been turned on.
|
||||
*/
|
||||
public void onWakeUpFinished() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onWakeUpFinished");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the device is going to sleep.
|
||||
*/
|
||||
public void onGoToSleepStarted(int reason) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onGoToSleepStarted");
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
mLastGoToSleepReason = reason;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the device has finished going to sleep and the
|
||||
* display has been turned off.
|
||||
*
|
||||
* This is a good time to make transitions that we don't want the user to see,
|
||||
* such as bringing the key guard to focus. There's no guarantee for this,
|
||||
* however because the user could turn the device on again at any time.
|
||||
* Some things may need to be protected by other mechanisms that defer screen on.
|
||||
*/
|
||||
public void onGoToSleepFinished() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onGoToSleepFinished");
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (mActualPowerState != POWER_STATE_ASLEEP) {
|
||||
mActualPowerState = POWER_STATE_ASLEEP;
|
||||
if (mUserActivityPending) {
|
||||
mUserActivityPending = false;
|
||||
mHandler.removeMessages(MSG_USER_ACTIVITY);
|
||||
}
|
||||
updatePendingBroadcastLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when there has been user activity.
|
||||
*/
|
||||
public void onUserActivity(int event, int uid) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onUserActivity: event=" + event + ", uid=" + uid);
|
||||
}
|
||||
|
||||
try {
|
||||
mBatteryStats.noteUserActivity(uid, event);
|
||||
} catch (RemoteException ex) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (!mUserActivityPending) {
|
||||
mUserActivityPending = true;
|
||||
Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePendingBroadcastLocked() {
|
||||
if (!mBroadcastInProgress
|
||||
&& mActualPowerState != POWER_STATE_UNKNOWN
|
||||
&& mActualPowerState != mBroadcastedPowerState) {
|
||||
mBroadcastInProgress = true;
|
||||
mSuspendBlocker.acquire();
|
||||
Message msg = mHandler.obtainMessage(MSG_BROADCAST);
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendUserActivity() {
|
||||
synchronized (mLock) {
|
||||
if (!mUserActivityPending) {
|
||||
return;
|
||||
}
|
||||
mUserActivityPending = false;
|
||||
}
|
||||
|
||||
mPolicy.userActivity();
|
||||
}
|
||||
|
||||
private void sendNextBroadcast() {
|
||||
final int powerState;
|
||||
final int goToSleepReason;
|
||||
synchronized (mLock) {
|
||||
if (mActualPowerState == POWER_STATE_UNKNOWN
|
||||
|| mActualPowerState == mBroadcastedPowerState) {
|
||||
mBroadcastInProgress = false;
|
||||
mSuspendBlocker.release();
|
||||
return;
|
||||
}
|
||||
|
||||
powerState = mActualPowerState;
|
||||
goToSleepReason = mLastGoToSleepReason;
|
||||
|
||||
mBroadcastedPowerState = powerState;
|
||||
mBroadcastStartTime = SystemClock.uptimeMillis();
|
||||
}
|
||||
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
|
||||
|
||||
if (powerState == POWER_STATE_AWAKE) {
|
||||
sendWakeUpBroadcast();
|
||||
} else {
|
||||
sendGoToSleepBroadcast(goToSleepReason);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendWakeUpBroadcast() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Sending wake up broadcast.");
|
||||
}
|
||||
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
|
||||
|
||||
mPolicy.screenTurningOn(mScreenOnListener);
|
||||
try {
|
||||
ActivityManagerNative.getDefault().wakingUp();
|
||||
} catch (RemoteException e) {
|
||||
// ignore it
|
||||
}
|
||||
|
||||
if (ActivityManagerNative.isSystemReady()) {
|
||||
mContext.sendOrderedBroadcast(mScreenOnIntent, null,
|
||||
mWakeUpBroadcastDone, mHandler, 0, null, null);
|
||||
} else {
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
|
||||
sendNextBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
|
||||
SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
|
||||
sendNextBroadcast();
|
||||
}
|
||||
};
|
||||
|
||||
private void sendGoToSleepBroadcast(int reason) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Sending go to sleep broadcast.");
|
||||
}
|
||||
|
||||
int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER;
|
||||
switch (reason) {
|
||||
case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
|
||||
why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
|
||||
break;
|
||||
case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
|
||||
why = WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
|
||||
|
||||
mPolicy.screenTurnedOff(why);
|
||||
try {
|
||||
ActivityManagerNative.getDefault().goingToSleep();
|
||||
} catch (RemoteException e) {
|
||||
// ignore it.
|
||||
}
|
||||
|
||||
if (ActivityManagerNative.isSystemReady()) {
|
||||
mContext.sendOrderedBroadcast(mScreenOffIntent, null,
|
||||
mGoToSleepBroadcastDone, mHandler, 0, null, null);
|
||||
} else {
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1);
|
||||
sendNextBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
|
||||
SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
|
||||
sendNextBroadcast();
|
||||
}
|
||||
};
|
||||
|
||||
private final class NotifierHandler extends Handler {
|
||||
public NotifierHandler(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_USER_ACTIVITY:
|
||||
sendUserActivity();
|
||||
break;
|
||||
|
||||
case MSG_BROADCAST:
|
||||
sendNextBroadcast();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.power;
|
||||
|
||||
import com.android.server.LightsService;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Sets the value of a light asynchronously.
|
||||
*
|
||||
* This is done to avoid blocking the looper on devices for which
|
||||
* setting the backlight brightness is especially slow.
|
||||
*/
|
||||
final class PhotonicModulator {
|
||||
private static final int UNKNOWN_LIGHT_VALUE = -1;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
private final LightsService.Light mLight;
|
||||
private final Executor mExecutor;
|
||||
private final SuspendBlocker mSuspendBlocker;
|
||||
|
||||
private boolean mPendingChange;
|
||||
private int mPendingLightValue;
|
||||
private int mActualLightValue;
|
||||
|
||||
public PhotonicModulator(Executor executor, LightsService.Light light,
|
||||
SuspendBlocker suspendBlocker) {
|
||||
mExecutor = executor;
|
||||
mLight = light;
|
||||
mSuspendBlocker = suspendBlocker;
|
||||
mPendingLightValue = UNKNOWN_LIGHT_VALUE;
|
||||
mActualLightValue = UNKNOWN_LIGHT_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously sets the backlight brightness.
|
||||
*
|
||||
* @param lightValue The new light value, from 0 to 255.
|
||||
*/
|
||||
public void setBrightness(int lightValue) {
|
||||
synchronized (mLock) {
|
||||
if (lightValue != mPendingLightValue) {
|
||||
mPendingLightValue = lightValue;
|
||||
if (!mPendingChange) {
|
||||
mPendingChange = true;
|
||||
mSuspendBlocker.acquire();
|
||||
mExecutor.execute(mTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable mTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (;;) {
|
||||
final int newLightValue;
|
||||
synchronized (mLock) {
|
||||
newLightValue = mPendingLightValue;
|
||||
if (newLightValue == mActualLightValue) {
|
||||
mSuspendBlocker.release();
|
||||
mPendingChange = false;
|
||||
return;
|
||||
}
|
||||
mActualLightValue = newLightValue;
|
||||
}
|
||||
mLight.setBrightness(newLightValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
131
services/java/com/android/server/power/RampAnimator.java
Normal file
131
services/java/com/android/server/power/RampAnimator.java
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.power;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.util.IntProperty;
|
||||
import android.view.Choreographer;
|
||||
|
||||
/**
|
||||
* A custom animator that progressively updates a property value at
|
||||
* a given variable rate until it reaches a particular target value.
|
||||
*/
|
||||
final class RampAnimator<T> {
|
||||
private final T mObject;
|
||||
private final IntProperty<T> mProperty;
|
||||
private final Choreographer mChoreographer;
|
||||
|
||||
private int mCurrentValue;
|
||||
private int mTargetValue;
|
||||
private int mRate;
|
||||
|
||||
private boolean mAnimating;
|
||||
private float mAnimatedValue; // higher precision copy of mCurrentValue
|
||||
private long mLastFrameTimeNanos;
|
||||
|
||||
private boolean mFirstTime = true;
|
||||
|
||||
public RampAnimator(T object, IntProperty<T> property) {
|
||||
mObject = object;
|
||||
mProperty = property;
|
||||
mChoreographer = Choreographer.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts animating towards the specified value.
|
||||
*
|
||||
* If this is the first time the property is being set, the value jumps
|
||||
* directly to the target.
|
||||
*
|
||||
* @param target The target value.
|
||||
* @param rate The convergence rate, in units per second.
|
||||
* @return True if the target differs from the previous target.
|
||||
*/
|
||||
public boolean animateTo(int target, int rate) {
|
||||
// Immediately jump to the target the first time.
|
||||
if (mFirstTime) {
|
||||
mFirstTime = false;
|
||||
mProperty.setValue(mObject, target);
|
||||
mCurrentValue = target;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adjust the rate based on the closest target.
|
||||
// If a faster rate is specified, then use the new rate so that we converge
|
||||
// more rapidly based on the new request.
|
||||
// If a slower rate is specified, then use the new rate only if the current
|
||||
// value is somewhere in between the new and the old target meaning that
|
||||
// we will be ramping in a different direction to get there.
|
||||
// Otherwise, continue at the previous rate.
|
||||
if (!mAnimating
|
||||
|| rate > mRate
|
||||
|| (target <= mCurrentValue && mCurrentValue <= mTargetValue)
|
||||
|| (mTargetValue <= mCurrentValue && mCurrentValue <= target)) {
|
||||
mRate = rate;
|
||||
}
|
||||
|
||||
final boolean changed = (mTargetValue != target);
|
||||
mTargetValue = target;
|
||||
|
||||
// Start animating.
|
||||
if (!mAnimating && target != mCurrentValue) {
|
||||
mAnimating = true;
|
||||
mAnimatedValue = mCurrentValue;
|
||||
mLastFrameTimeNanos = System.nanoTime();
|
||||
postCallback();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
private void postCallback() {
|
||||
mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mCallback, null);
|
||||
}
|
||||
|
||||
private final Runnable mCallback = new Runnable() {
|
||||
@Override // Choreographer callback
|
||||
public void run() {
|
||||
final long frameTimeNanos = mChoreographer.getFrameTimeNanos();
|
||||
final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos)
|
||||
* 0.000000001f;
|
||||
final float amount = timeDelta * mRate / ValueAnimator.getDurationScale();
|
||||
mLastFrameTimeNanos = frameTimeNanos;
|
||||
|
||||
// Advance the animated value towards the target at the specified rate
|
||||
// and clamp to the target. This gives us the new current value but
|
||||
// we keep the animated value around to allow for fractional increments
|
||||
// towards the target.
|
||||
int oldCurrentValue = mCurrentValue;
|
||||
if (mTargetValue > mCurrentValue) {
|
||||
mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue);
|
||||
} else {
|
||||
mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue);
|
||||
}
|
||||
mCurrentValue = (int)Math.round(mAnimatedValue);
|
||||
|
||||
if (oldCurrentValue != mCurrentValue) {
|
||||
mProperty.setValue(mObject, mCurrentValue);
|
||||
}
|
||||
|
||||
if (mTargetValue != mCurrentValue) {
|
||||
postCallback();
|
||||
} else {
|
||||
mAnimating = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
43
services/java/com/android/server/power/SuspendBlocker.java
Normal file
43
services/java/com/android/server/power/SuspendBlocker.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.power;
|
||||
|
||||
/**
|
||||
* Low-level suspend blocker mechanism equivalent to holding a partial wake lock.
|
||||
*
|
||||
* This interface is used internally to avoid introducing internal dependencies
|
||||
* on the high-level wake lock mechanism.
|
||||
*/
|
||||
interface SuspendBlocker {
|
||||
/**
|
||||
* Acquires the suspend blocker.
|
||||
* Prevents the CPU from going to sleep.
|
||||
*
|
||||
* Calls to acquire() nest and must be matched by the same number
|
||||
* of calls to release().
|
||||
*/
|
||||
void acquire();
|
||||
|
||||
/**
|
||||
* Releases the suspend blocker.
|
||||
* Allows the CPU to go to sleep if no other suspend blockers are held.
|
||||
*
|
||||
* It is an error to call release() if the suspend blocker has not been acquired.
|
||||
* The system may crash.
|
||||
*/
|
||||
void release();
|
||||
}
|
||||
@@ -855,7 +855,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
android.os.Process.setThreadPriority(
|
||||
android.os.Process.THREAD_PRIORITY_FOREGROUND);
|
||||
android.os.Process.setCanSelfBackground(false);
|
||||
mPolicy.init(mContext, mService, mService, mPM);
|
||||
mPolicy.init(mContext, mService, mService);
|
||||
mService.mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
|
||||
* TYPE_LAYER_MULTIPLIER
|
||||
+ TYPE_LAYER_OFFSET;
|
||||
@@ -910,7 +910,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
mContext.registerReceiver(mBroadcastReceiver, filter);
|
||||
|
||||
mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
|
||||
| PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
|
||||
| PowerManager.ON_AFTER_RELEASE, PowerManager.KEEP_SCREEN_ON_FLAG_TAG);
|
||||
mHoldingScreenWakeLock.setReferenceCounted(false);
|
||||
|
||||
mInputManager = new InputManagerService(context, mInputMonitor);
|
||||
@@ -9074,16 +9074,16 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
setHoldScreenLocked(mInnerFields.mHoldScreen != null);
|
||||
if (!mDisplayFrozen) {
|
||||
if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
|
||||
mPowerManager.setScreenBrightnessOverride(-1);
|
||||
mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
|
||||
} else {
|
||||
mPowerManager.setScreenBrightnessOverride((int)
|
||||
(mInnerFields.mScreenBrightness * PowerManager.BRIGHTNESS_ON));
|
||||
mPowerManager.setScreenBrightnessOverrideFromWindowManager(
|
||||
toBrightnessOverride(mInnerFields.mScreenBrightness));
|
||||
}
|
||||
if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
|
||||
mPowerManager.setButtonBrightnessOverride(-1);
|
||||
mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1);
|
||||
} else {
|
||||
mPowerManager.setButtonBrightnessOverride((int)
|
||||
(mInnerFields.mButtonBrightness * PowerManager.BRIGHTNESS_ON));
|
||||
mPowerManager.setButtonBrightnessOverrideFromWindowManager(
|
||||
toBrightnessOverride(mInnerFields.mButtonBrightness));
|
||||
}
|
||||
}
|
||||
if (mInnerFields.mHoldScreen != mHoldingScreenOn) {
|
||||
@@ -9094,8 +9094,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
|
||||
if (mTurnOnScreen) {
|
||||
if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
|
||||
mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
|
||||
PowerManager.USER_ACTIVITY_EVENT_BUTTON, true);
|
||||
mPowerManager.wakeUp(SystemClock.uptimeMillis());
|
||||
mTurnOnScreen = false;
|
||||
}
|
||||
|
||||
@@ -9126,6 +9125,10 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private int toBrightnessOverride(float value) {
|
||||
return (int)(value * PowerManager.BRIGHTNESS_ON);
|
||||
}
|
||||
|
||||
void checkDrawnWindowsLocked() {
|
||||
if (mWaitingForDrawn.size() > 0) {
|
||||
for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
|
||||
|
||||
@@ -120,7 +120,10 @@ static void setLight_native(JNIEnv *env, jobject clazz, int ptr,
|
||||
state.flashOffMS = offMS;
|
||||
state.brightnessMode = brightnessMode;
|
||||
|
||||
devices->lights[light]->set_light(devices->lights[light], &state);
|
||||
{
|
||||
ALOGD_IF_SLOW(50, "Excessive delay setting light");
|
||||
devices->lights[light]->set_light(devices->lights[light], &state);
|
||||
}
|
||||
}
|
||||
|
||||
static JNINativeMethod method_table[] = {
|
||||
|
||||
@@ -143,7 +143,7 @@ static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t styl
|
||||
|
||||
enum {
|
||||
WM_ACTION_PASS_TO_USER = 1,
|
||||
WM_ACTION_POKE_USER_ACTIVITY = 2,
|
||||
WM_ACTION_WAKE_UP = 2,
|
||||
WM_ACTION_GO_TO_SLEEP = 4,
|
||||
};
|
||||
|
||||
@@ -899,11 +899,11 @@ void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
|
||||
android_server_PowerManagerService_goToSleep(when);
|
||||
}
|
||||
|
||||
if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
|
||||
if (wmActions & WM_ACTION_WAKE_UP) {
|
||||
#if DEBUG_INPUT_DISPATCHER_POLICY
|
||||
ALOGD("handleInterceptActions: Poking user activity.");
|
||||
ALOGD("handleInterceptActions: Waking up.");
|
||||
#endif
|
||||
android_server_PowerManagerService_userActivity(when, USER_ACTIVITY_EVENT_BUTTON);
|
||||
android_server_PowerManagerService_wakeUp(when);
|
||||
}
|
||||
|
||||
if (wmActions & WM_ACTION_PASS_TO_USER) {
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "JNIHelp.h"
|
||||
#include "jni.h"
|
||||
|
||||
#include <ScopedUtfChars.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
@@ -28,6 +30,7 @@
|
||||
#include <utils/Timers.h>
|
||||
#include <utils/misc.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Log.h>
|
||||
#include <hardware/power.h>
|
||||
#include <hardware_legacy/power.h>
|
||||
#include <cutils/android_reboot.h>
|
||||
@@ -42,8 +45,9 @@ namespace android {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static struct {
|
||||
jmethodID goToSleep;
|
||||
jmethodID userActivity;
|
||||
jmethodID wakeUpFromNative;
|
||||
jmethodID goToSleepFromNative;
|
||||
jmethodID userActivityFromNative;
|
||||
} gPowerManagerServiceClassInfo;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -106,9 +110,21 @@ void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t
|
||||
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.userActivity,
|
||||
nanoseconds_to_milliseconds(eventTime), false, eventType, false);
|
||||
checkAndClearExceptionFromCallback(env, "userActivity");
|
||||
env->CallVoidMethod(gPowerManagerServiceObj,
|
||||
gPowerManagerServiceClassInfo.userActivityFromNative,
|
||||
nanoseconds_to_milliseconds(eventTime), eventType, 0);
|
||||
checkAndClearExceptionFromCallback(env, "userActivityFromNative");
|
||||
}
|
||||
}
|
||||
|
||||
void android_server_PowerManagerService_wakeUp(nsecs_t eventTime) {
|
||||
if (gPowerManagerServiceObj) {
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
env->CallVoidMethod(gPowerManagerServiceObj,
|
||||
gPowerManagerServiceClassInfo.wakeUpFromNative,
|
||||
nanoseconds_to_milliseconds(eventTime));
|
||||
checkAndClearExceptionFromCallback(env, "wakeUpFromNative");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,9 +132,10 @@ void android_server_PowerManagerService_goToSleep(nsecs_t eventTime) {
|
||||
if (gPowerManagerServiceObj) {
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.goToSleep,
|
||||
nanoseconds_to_milliseconds(eventTime));
|
||||
checkAndClearExceptionFromCallback(env, "goToSleep");
|
||||
env->CallVoidMethod(gPowerManagerServiceObj,
|
||||
gPowerManagerServiceClassInfo.goToSleepFromNative,
|
||||
nanoseconds_to_milliseconds(eventTime), 0);
|
||||
checkAndClearExceptionFromCallback(env, "goToSleepFromNative");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,68 +154,62 @@ static void nativeInit(JNIEnv* env, jobject obj) {
|
||||
}
|
||||
|
||||
static void nativeSetPowerState(JNIEnv* env,
|
||||
jobject serviceObj, jboolean screenOn, jboolean screenBright) {
|
||||
jclass clazz, jboolean screenOn, jboolean screenBright) {
|
||||
AutoMutex _l(gPowerManagerLock);
|
||||
gScreenOn = screenOn;
|
||||
gScreenBright = screenBright;
|
||||
}
|
||||
|
||||
static void nativeStartSurfaceFlingerAnimation(JNIEnv* env,
|
||||
jobject obj, jint mode) {
|
||||
// this is not handled by surfaceflinger anymore
|
||||
static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
|
||||
ScopedUtfChars name(env, nameStr);
|
||||
acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
|
||||
}
|
||||
|
||||
static void nativeAcquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj) {
|
||||
if (idObj == NULL) {
|
||||
jniThrowNullPointerException(env, "id is null");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *id = env->GetStringUTFChars(idObj, NULL);
|
||||
|
||||
acquire_wake_lock(lock, id);
|
||||
|
||||
env->ReleaseStringUTFChars(idObj, id);
|
||||
static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
|
||||
ScopedUtfChars name(env, nameStr);
|
||||
release_wake_lock(name.c_str());
|
||||
}
|
||||
|
||||
static void nativeReleaseWakeLock(JNIEnv *env, jobject clazz, jstring idObj) {
|
||||
if (idObj == NULL) {
|
||||
jniThrowNullPointerException(env, "id is null");
|
||||
return ;
|
||||
}
|
||||
|
||||
const char *id = env->GetStringUTFChars(idObj, NULL);
|
||||
|
||||
release_wake_lock(id);
|
||||
|
||||
env->ReleaseStringUTFChars(idObj, id);
|
||||
|
||||
}
|
||||
|
||||
static int nativeSetScreenState(JNIEnv *env, jobject clazz, jboolean on) {
|
||||
static void nativeSetScreenState(JNIEnv *env, jclass clazz, jboolean on) {
|
||||
sp<ISurfaceComposer> s(ComposerService::getComposerService());
|
||||
if (on) {
|
||||
autosuspend_disable();
|
||||
{
|
||||
ALOGD_IF_SLOW(50, "Excessive delay in autosuspend_disable() while turning screen on");
|
||||
autosuspend_disable();
|
||||
}
|
||||
|
||||
if (gPowerModule) {
|
||||
ALOGD_IF_SLOW(10, "Excessive delay in setInteractive(true) while turning screen on");
|
||||
gPowerModule->setInteractive(gPowerModule, true);
|
||||
}
|
||||
s->unblank();
|
||||
|
||||
{
|
||||
ALOGD_IF_SLOW(20, "Excessive delay in unblank() while turning screen on");
|
||||
s->unblank();
|
||||
}
|
||||
} else {
|
||||
s->blank();
|
||||
{
|
||||
ALOGD_IF_SLOW(20, "Excessive delay in blank() while turning screen off");
|
||||
s->blank();
|
||||
}
|
||||
|
||||
if (gPowerModule) {
|
||||
ALOGD_IF_SLOW(10, "Excessive delay in setInteractive(false) while turning screen off");
|
||||
gPowerModule->setInteractive(gPowerModule, false);
|
||||
}
|
||||
autosuspend_enable();
|
||||
}
|
||||
|
||||
return 0;
|
||||
{
|
||||
ALOGD_IF_SLOW(50, "Excessive delay in autosuspend_enable() while turning screen off");
|
||||
autosuspend_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nativeShutdown(JNIEnv *env, jobject clazz) {
|
||||
static void nativeShutdown(JNIEnv *env, jclass clazz) {
|
||||
android_reboot(ANDROID_RB_POWEROFF, 0, 0);
|
||||
}
|
||||
|
||||
static void nativeReboot(JNIEnv *env, jobject clazz, jstring reason) {
|
||||
static void nativeReboot(JNIEnv *env, jclass clazz, jstring reason) {
|
||||
if (reason == NULL) {
|
||||
android_reboot(ANDROID_RB_RESTART, 0, 0);
|
||||
} else {
|
||||
@@ -218,13 +229,11 @@ static JNINativeMethod gPowerManagerServiceMethods[] = {
|
||||
(void*) nativeInit },
|
||||
{ "nativeSetPowerState", "(ZZ)V",
|
||||
(void*) nativeSetPowerState },
|
||||
{ "nativeStartSurfaceFlingerAnimation", "(I)V",
|
||||
(void*) nativeStartSurfaceFlingerAnimation },
|
||||
{ "nativeAcquireWakeLock", "(ILjava/lang/String;)V",
|
||||
(void*) nativeAcquireWakeLock },
|
||||
{ "nativeReleaseWakeLock", "(Ljava/lang/String;)V",
|
||||
(void*) nativeReleaseWakeLock },
|
||||
{ "nativeSetScreenState", "(Z)I",
|
||||
{ "nativeAcquireSuspendBlocker", "(Ljava/lang/String;)V",
|
||||
(void*) nativeAcquireSuspendBlocker },
|
||||
{ "nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V",
|
||||
(void*) nativeReleaseSuspendBlocker },
|
||||
{ "nativeSetScreenState", "(Z)V",
|
||||
(void*) nativeSetScreenState },
|
||||
{ "nativeShutdown", "()V",
|
||||
(void*) nativeShutdown },
|
||||
@@ -254,11 +263,14 @@ int register_android_server_PowerManagerService(JNIEnv* env) {
|
||||
jclass clazz;
|
||||
FIND_CLASS(clazz, "com/android/server/power/PowerManagerService");
|
||||
|
||||
GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, clazz,
|
||||
"goToSleep", "(J)V");
|
||||
GET_METHOD_ID(gPowerManagerServiceClassInfo.wakeUpFromNative, clazz,
|
||||
"wakeUpFromNative", "(J)V");
|
||||
|
||||
GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivity, clazz,
|
||||
"userActivity", "(JZIZ)V");
|
||||
GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleepFromNative, clazz,
|
||||
"goToSleepFromNative", "(JI)V");
|
||||
|
||||
GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivityFromNative, clazz,
|
||||
"userActivityFromNative", "(JII)V");
|
||||
|
||||
// Initialize
|
||||
for (int i = 0; i <= USER_ACTIVITY_EVENT_LAST; i++) {
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace android {
|
||||
extern bool android_server_PowerManagerService_isScreenOn();
|
||||
extern bool android_server_PowerManagerService_isScreenBright();
|
||||
extern void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType);
|
||||
extern void android_server_PowerManagerService_wakeUp(nsecs_t eventTime);
|
||||
extern void android_server_PowerManagerService_goToSleep(nsecs_t eventTime);
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -16,32 +16,15 @@
|
||||
|
||||
package com.android.statusbartest;
|
||||
|
||||
import android.app.ListActivity;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.view.View;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.IPowerManager;
|
||||
import android.widget.ListView;
|
||||
import android.content.Intent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.StatusBarManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Vibrator;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.LocalPowerManager;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
import android.net.Uri;
|
||||
import android.os.SystemClock;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.Toast;
|
||||
import android.os.PowerManager;
|
||||
|
||||
public class PowerTest extends TestActivity
|
||||
@@ -101,6 +84,28 @@ public class PowerTest extends TestActivity
|
||||
mProx.release(PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
|
||||
}
|
||||
},
|
||||
new Test("Enable proximity, wait 5 seconds then disable") {
|
||||
public void run() {
|
||||
mProx.acquire();
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mProx.release();
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
},
|
||||
new Test("Enable proximity, wait 5 seconds then disable (WAIT_FOR_PROXIMITY_NEGATIVE)") {
|
||||
public void run() {
|
||||
mProx.acquire();
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mProx.release(PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
},
|
||||
new Test("Touch events don't poke") {
|
||||
public void run() {
|
||||
mPokeState |= LocalPowerManager.POKE_LOCK_IGNORE_TOUCH_EVENTS;
|
||||
|
||||
@@ -440,7 +440,7 @@ public final class BridgeContext extends Context {
|
||||
}
|
||||
|
||||
if (POWER_SERVICE.equals(service)) {
|
||||
return new PowerManager(new BridgePowerManager(), new Handler());
|
||||
return new PowerManager(this, new BridgePowerManager(), new Handler());
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Unsupported Service: " + service);
|
||||
|
||||
@@ -39,7 +39,7 @@ public class BridgePowerManager implements IPowerManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acquireWakeLock(int arg0, IBinder arg1, String arg2, WorkSource arg3)
|
||||
public void acquireWakeLock(IBinder arg0, int arg1, String arg2, WorkSource arg3)
|
||||
throws RemoteException {
|
||||
// pass for now.
|
||||
}
|
||||
@@ -55,18 +55,7 @@ public class BridgePowerManager implements IPowerManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSupportedWakeLockFlags() throws RemoteException {
|
||||
// pass for now.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goToSleep(long arg0) throws RemoteException {
|
||||
// pass for now.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goToSleepWithReason(long arg0, int arg1) throws RemoteException {
|
||||
public void goToSleep(long arg0, int arg1) throws RemoteException {
|
||||
// pass for now.
|
||||
}
|
||||
|
||||
@@ -91,17 +80,17 @@ public class BridgePowerManager implements IPowerManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoBrightnessAdjustment(float arg0) throws RemoteException {
|
||||
public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float arg0) throws RemoteException {
|
||||
// pass for now.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBacklightBrightness(int arg0) throws RemoteException {
|
||||
public void setTemporaryScreenBrightnessSettingOverride(int arg0) throws RemoteException {
|
||||
// pass for now.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaximumScreenOffTimeount(int arg0) throws RemoteException {
|
||||
public void setMaximumScreenOffTimeoutFromDeviceAdmin(int arg0) throws RemoteException {
|
||||
// pass for now.
|
||||
}
|
||||
|
||||
@@ -121,12 +110,18 @@ public class BridgePowerManager implements IPowerManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userActivity(long arg0, boolean arg1) throws RemoteException {
|
||||
public boolean isWakeLockLevelSupported(int level) throws RemoteException {
|
||||
// pass for now.
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userActivity(long time, int event, int flags) throws RemoteException {
|
||||
// pass for now.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userActivityWithForce(long arg0, boolean arg1, boolean arg2) throws RemoteException {
|
||||
public void wakeUp(long time) throws RemoteException {
|
||||
// pass for now.
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user