Merge "Blank or unblank all displays as need." into jb-mr1-dev

This commit is contained in:
Jeff Brown
2012-10-09 00:02:46 -07:00
committed by Android (Google) Code Review
10 changed files with 242 additions and 65 deletions

View File

@@ -266,6 +266,8 @@ public class Surface implements Parcelable {
IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect);
private static native boolean nativeGetDisplayInfo(
IBinder displayToken, PhysicalDisplayInfo outInfo);
private static native void nativeBlankDisplay(IBinder displayToken);
private static native void nativeUnblankDisplay(IBinder displayToken);
private native void nativeCopyFrom(Surface other);
private native void nativeTransferFrom(Surface other);
@@ -638,6 +640,22 @@ public class Surface implements Parcelable {
return nativeGetDisplayInfo(displayToken, outInfo);
}
/** @hide */
public static void blankDisplay(IBinder displayToken) {
if (displayToken == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
nativeBlankDisplay(displayToken);
}
/** @hide */
public static void unblankDisplay(IBinder displayToken) {
if (displayToken == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
nativeUnblankDisplay(displayToken);
}
/**
* Copy another surface to this one. This surface now holds a reference
* to the same data as the original surface, and is -not- the owner.

View File

@@ -48,6 +48,7 @@
#include <android_runtime/android_view_SurfaceSession.h>
#include <android_runtime/android_graphics_SurfaceTexture.h>
#include <utils/misc.h>
#include <utils/Log.h>
#include <ScopedUtfChars.h>
@@ -710,6 +711,22 @@ static jboolean nativeGetDisplayInfo(JNIEnv* env, jclass clazz,
return JNI_TRUE;
}
static void nativeBlankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
if (token == NULL) return;
ALOGD_IF_SLOW(100, "Excessive delay in blankDisplay() while turning screen off");
SurfaceComposerClient::blankDisplay(token);
}
static void nativeUnblankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
if (token == NULL) return;
ALOGD_IF_SLOW(100, "Excessive delay in unblankDisplay() while turning screen on");
SurfaceComposerClient::unblankDisplay(token);
}
// ----------------------------------------------------------------------------
static void nativeCopyFrom(JNIEnv* env, jobject surfaceObj, jobject otherObj) {
@@ -832,6 +849,10 @@ static JNINativeMethod gSurfaceMethods[] = {
(void*)nativeSetDisplayProjection },
{"nativeGetDisplayInfo", "(Landroid/os/IBinder;Landroid/view/Surface$PhysicalDisplayInfo;)Z",
(void*)nativeGetDisplayInfo },
{"nativeBlankDisplay", "(Landroid/os/IBinder;)V",
(void*)nativeBlankDisplay },
{"nativeUnblankDisplay", "(Landroid/os/IBinder;)V",
(void*)nativeUnblankDisplay },
{"nativeCopyFrom", "(Landroid/view/Surface;)V",
(void*)nativeCopyFrom },
{"nativeTransferFrom", "(Landroid/view/Surface;)V",

View File

@@ -104,6 +104,18 @@ abstract class DisplayDevice {
public void performTraversalInTransactionLocked() {
}
/**
* Blanks the display, if supported.
*/
public void blankLocked() {
}
/**
* Unblanks the display, if supported.
*/
public void unblankLocked() {
}
/**
* Sets the display layer stack while in a transaction.
*/

View File

@@ -103,6 +103,10 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
private static final int MSG_REQUEST_TRAVERSAL = 4;
private static final int MSG_UPDATE_VIEWPORT = 5;
private static final int DISPLAY_BLANK_STATE_UNKNOWN = 0;
private static final int DISPLAY_BLANK_STATE_BLANKED = 1;
private static final int DISPLAY_BLANK_STATE_UNBLANKED = 2;
private final Context mContext;
private final boolean mHeadless;
private final DisplayManagerHandler mHandler;
@@ -141,6 +145,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
new SparseArray<LogicalDisplay>();
private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
// Set to true if all displays have been blanked by the power manager.
private int mAllDisplayBlankStateFromPowerManager;
// Set to true when there are pending display changes that have yet to be applied
// to the surface flinger state.
private boolean mPendingTraversal;
@@ -285,6 +292,40 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
}
}
/**
* Called by the power manager to blank all displays.
*/
public void blankAllDisplaysFromPowerManager() {
synchronized (mSyncRoot) {
if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) {
mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED;
final int count = mDisplayDevices.size();
for (int i = 0; i < count; i++) {
DisplayDevice device = mDisplayDevices.get(i);
device.blankLocked();
}
}
}
}
/**
* Called by the power manager to unblank all displays.
*/
public void unblankAllDisplaysFromPowerManager() {
synchronized (mSyncRoot) {
if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) {
mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED;
final int count = mDisplayDevices.size();
for (int i = 0; i < count; i++) {
DisplayDevice device = mDisplayDevices.get(i);
device.unblankLocked();
}
}
}
}
/**
* Returns information about the specified logical display.
*
@@ -528,6 +569,17 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
mDisplayDevices.add(device);
addLogicalDisplayLocked(device);
scheduleTraversalLocked(false);
// Blank or unblank the display immediately to match the state requested
// by the power manager (if known).
switch (mAllDisplayBlankStateFromPowerManager) {
case DISPLAY_BLANK_STATE_BLANKED:
device.blankLocked();
break;
case DISPLAY_BLANK_STATE_UNBLANKED:
device.unblankLocked();
break;
}
}
}
@@ -788,9 +840,18 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
}
pw.println("DISPLAY MANAGER (dumpsys display)");
pw.println(" mHeadless=" + mHeadless);
synchronized (mSyncRoot) {
pw.println(" mHeadless=" + mHeadless);
pw.println(" mOnlyCode=" + mOnlyCore);
pw.println(" mSafeMode=" + mSafeMode);
pw.println(" mPendingTraversal=" + mPendingTraversal);
pw.println(" mAllDisplayBlankStateFromPowerManager="
+ mAllDisplayBlankStateFromPowerManager);
pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
pw.println(" mDefaultViewport=" + mDefaultViewport);
pw.println(" mExternalTouchViewport=" + mExternalTouchViewport);
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.increaseIndent();
@@ -817,10 +878,6 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
pw.println(" Display " + displayId + ":");
display.dumpLocked(ipw);
}
pw.println();
pw.println("Default viewport: " + mDefaultViewport);
pw.println("External touch viewport: " + mExternalTouchViewport);
}
}

View File

@@ -92,6 +92,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
private boolean mBlanked;
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
PhysicalDisplayInfo phys) {
@@ -149,11 +150,24 @@ final class LocalDisplayAdapter extends DisplayAdapter {
return mInfo;
}
@Override
public void blankLocked() {
mBlanked = true;
Surface.blankDisplay(getDisplayTokenLocked());
}
@Override
public void unblankLocked() {
mBlanked = false;
Surface.unblankDisplay(getDisplayTokenLocked());
}
@Override
public void dumpLocked(PrintWriter pw) {
super.dumpLocked(pw);
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
pw.println("mPhys=" + mPhys);
pw.println("mBlanked=" + mBlanked);
}
}

View File

@@ -0,0 +1,25 @@
/*
* 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;
/**
* Blanks or unblanks all displays.
*/
interface DisplayBlanker {
public void blankAllDisplays();
public void unblankAllDisplays();
}

View File

@@ -159,6 +159,9 @@ final class DisplayPowerController {
// A suspend blocker.
private final SuspendBlocker mSuspendBlocker;
// The display blanker.
private final DisplayBlanker mDisplayBlanker;
// Our handler.
private final DisplayControllerHandler mHandler;
@@ -343,10 +346,12 @@ final class DisplayPowerController {
*/
public DisplayPowerController(Looper looper, Context context, Notifier notifier,
LightsService lights, TwilightService twilight, SuspendBlocker suspendBlocker,
DisplayBlanker displayBlanker,
Callbacks callbacks, Handler callbackHandler) {
mHandler = new DisplayControllerHandler(looper);
mNotifier = notifier;
mSuspendBlocker = suspendBlocker;
mDisplayBlanker = displayBlanker;
mCallbacks = callbacks;
mCallbackHandler = callbackHandler;
@@ -520,7 +525,8 @@ final class DisplayPowerController {
new ElectronBeam(display),
new PhotonicModulator(executor,
mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT),
mSuspendBlocker));
mSuspendBlocker),
mDisplayBlanker);
mElectronBeamOnAnimator = ObjectAnimator.ofFloat(
mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f);

View File

@@ -51,7 +51,8 @@ final class DisplayPowerState {
private final Choreographer mChoreographer;
private final ElectronBeam mElectronBeam;
private final PhotonicModulator mScreenBrightnessModulator;
private final PhotonicModulator mPhotonicModulator;
private final DisplayBlanker mDisplayBlanker;
private int mDirty;
private boolean mScreenOn;
@@ -61,10 +62,11 @@ final class DisplayPowerState {
private Runnable mCleanListener;
public DisplayPowerState(ElectronBeam electronBean,
PhotonicModulator screenBrightnessModulator) {
PhotonicModulator photonicModulator, DisplayBlanker displayBlanker) {
mChoreographer = Choreographer.getInstance();
mElectronBeam = electronBean;
mScreenBrightnessModulator = screenBrightnessModulator;
mPhotonicModulator = photonicModulator;
mDisplayBlanker = displayBlanker;
// At boot time, we know that the screen is on and the electron beam
// animation is not playing. We don't know the screen's brightness though,
@@ -238,8 +240,8 @@ final class DisplayPowerState {
private void apply() {
if (mDirty != 0) {
if ((mDirty & DIRTY_SCREEN_ON) != 0 && !mScreenOn) {
mScreenBrightnessModulator.setBrightness(0, true /*sync*/);
PowerManagerService.nativeSetScreenState(false);
mPhotonicModulator.setBrightness(0, true /*sync*/);
mDisplayBlanker.blankAllDisplays();
}
if ((mDirty & DIRTY_ELECTRON_BEAM) != 0) {
@@ -247,12 +249,12 @@ final class DisplayPowerState {
}
if ((mDirty & DIRTY_SCREEN_ON) != 0 && mScreenOn) {
PowerManagerService.nativeSetScreenState(true);
mDisplayBlanker.unblankAllDisplays();
}
if ((mDirty & (DIRTY_BRIGHTNESS | DIRTY_SCREEN_ON | DIRTY_ELECTRON_BEAM)) != 0
&& mScreenOn) {
mScreenBrightnessModulator.setBrightness(
mPhotonicModulator.setBrightness(
(int)(mScreenBrightness * mElectronBeamLevel), false /*sync*/);
}

View File

@@ -155,6 +155,7 @@ public final class PowerManagerService extends IPowerManager.Stub
private Context mContext;
private LightsService mLightsService;
private BatteryService mBatteryService;
private DisplayManagerService mDisplayManagerService;
private IBatteryStats mBatteryStats;
private HandlerThread mHandlerThread;
private PowerManagerHandler mHandler;
@@ -230,6 +231,9 @@ public final class PowerManagerService extends IPowerManager.Stub
// screen is coming up.
private final ScreenOnBlockerImpl mScreenOnBlocker;
// The display blanker used to turn the screen on or off.
private final DisplayBlankerImpl mDisplayBlanker;
// True if systemReady() has been called.
private boolean mSystemReady;
@@ -319,14 +323,15 @@ public final class PowerManagerService extends IPowerManager.Stub
private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
private static native void nativeAcquireSuspendBlocker(String name);
private static native void nativeReleaseSuspendBlocker(String name);
static native void nativeSetScreenState(boolean on);
private static native void nativeSetInteractive(boolean enable);
private static native void nativeSetAutoSuspend(boolean enable);
public PowerManagerService() {
synchronized (mLock) {
mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService");
mWakeLockSuspendBlocker.acquire();
mScreenOnBlocker = new ScreenOnBlockerImpl();
mDisplayBlanker = new DisplayBlankerImpl();
mHoldingWakeLockSuspendBlocker = true;
mWakefulness = WAKEFULNESS_AWAKE;
}
@@ -342,23 +347,24 @@ public final class PowerManagerService extends IPowerManager.Stub
public void init(Context context, LightsService ls,
ActivityManagerService am, BatteryService bs, IBatteryStats bss,
DisplayManagerService dm) {
mContext = context;
mLightsService = ls;
mBatteryService = bs;
mBatteryStats = bss;
mDisplayManagerService = dm;
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
Watchdog.getInstance().addMonitor(this);
// Forcibly turn the screen on at boot so that it is in a known power state.
// We do this in init() rather than in the constructor because setting the
// screen state requires a call into surface flinger which then needs to call back
// into the activity manager to check permissions. Unfortunately the
// activity manager is not running when the constructor is called, so we
// have to defer setting the screen state until this point.
nativeSetScreenState(true);
mContext = context;
mLightsService = ls;
mBatteryService = bs;
mBatteryStats = bss;
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
Watchdog.getInstance().addMonitor(this);
mDisplayBlanker.unblankAllDisplays();
}
public void setPolicy(WindowManagerPolicy policy) {
@@ -388,7 +394,7 @@ public final class PowerManagerService extends IPowerManager.Stub
mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
mContext, mNotifier, mLightsService, twilight,
createSuspendBlockerLocked("PowerManagerService.Display"),
mDisplayPowerControllerCallbacks, mHandler);
mDisplayBlanker, mDisplayPowerControllerCallbacks, mHandler);
mSettingsObserver = new SettingsObserver(mHandler);
mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);
@@ -2106,6 +2112,9 @@ public final class PowerManagerService extends IPowerManager.Stub
pw.println();
pw.println("Screen On Blocker: " + mScreenOnBlocker);
pw.println();
pw.println("Display Blanker: " + mDisplayBlanker);
dpc = mDisplayPowerController;
}
@@ -2397,5 +2406,36 @@ public final class PowerManagerService extends IPowerManager.Stub
return "held=" + (mNestCount != 0) + ", mNestCount=" + mNestCount;
}
}
};
}
private final class DisplayBlankerImpl implements DisplayBlanker {
private boolean mBlanked;
@Override
public void blankAllDisplays() {
synchronized (this) {
mBlanked = true;
mDisplayManagerService.blankAllDisplaysFromPowerManager();
nativeSetInteractive(false);
nativeSetAutoSuspend(true);
}
}
@Override
public void unblankAllDisplays() {
synchronized (this) {
nativeSetAutoSuspend(false);
nativeSetInteractive(true);
mDisplayManagerService.unblankAllDisplaysFromPowerManager();
mBlanked = false;
}
}
@Override
public String toString() {
synchronized (this) {
return "blanked=" + mBlanked;
}
}
}
}

View File

@@ -26,7 +26,6 @@
#include <limits.h>
#include <android_runtime/AndroidRuntime.h>
#include <gui/ISurfaceComposer.h>
#include <utils/Timers.h>
#include <utils/misc.h>
#include <utils/String8.h>
@@ -36,8 +35,6 @@
#include <cutils/android_reboot.h>
#include <suspend/autosuspend.h>
#include <private/gui/ComposerService.h>
#include "com_android_server_power_PowerManagerService.h"
namespace android {
@@ -170,40 +167,23 @@ static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameS
release_wake_lock(name.c_str());
}
static void nativeSetScreenState(JNIEnv *env, jclass clazz, jboolean on) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (on) {
{
ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on");
autosuspend_disable();
}
if (gPowerModule) {
ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
gPowerModule->setInteractive(gPowerModule, true);
}
const sp<IBinder>& display = s->getBuiltInDisplay(0); // TODO: support multiple displays
{
ALOGD_IF_SLOW(100, "Excessive delay in unblank() while turning screen on");
s->unblank(display);
}
static void nativeSetInteractive(JNIEnv *env, jclass clazz, jboolean enable) {
if (enable) {
ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
gPowerModule->setInteractive(gPowerModule, true);
} else {
const sp<IBinder>& display = s->getBuiltInDisplay(0); // TODO: support multiple displays
{
ALOGD_IF_SLOW(100, "Excessive delay in blank() while turning screen off");
s->blank(display);
}
ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off");
gPowerModule->setInteractive(gPowerModule, false);
}
}
if (gPowerModule) {
ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off");
gPowerModule->setInteractive(gPowerModule, false);
}
{
ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off");
autosuspend_enable();
}
static void nativeSetAutoSuspend(JNIEnv *env, jclass clazz, jboolean enable) {
if (enable) {
ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off");
autosuspend_enable();
} else {
ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on");
autosuspend_disable();
}
}
@@ -235,8 +215,10 @@ static JNINativeMethod gPowerManagerServiceMethods[] = {
(void*) nativeAcquireSuspendBlocker },
{ "nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V",
(void*) nativeReleaseSuspendBlocker },
{ "nativeSetScreenState", "(Z)V",
(void*) nativeSetScreenState },
{ "nativeSetInteractive", "(Z)V",
(void*) nativeSetInteractive },
{ "nativeSetAutoSuspend", "(Z)V",
(void*) nativeSetAutoSuspend },
{ "nativeShutdown", "()V",
(void*) nativeShutdown },
{ "nativeReboot", "(Ljava/lang/String;)V",