Ignore draw requests when the display is off
When WindowManagerService's events are enabled/disabled, the state of the display is dispatched to the known windows. This allows ViewRootImpl to ignore draw requests until the screen is turned back on. This can potentially lead to significant battery savings. For instance, a launcher widget showing a repeating animation will cause the CPU and the GPU to wake up regularly without this change. (Change submitted by Intel and merged manually) Change-Id: I7f93b0e60c3e6de1705f619e80860c36b1cdb978
This commit is contained in:
@@ -49,6 +49,7 @@ oneway interface IWindow {
|
||||
boolean reportDraw, in Configuration newConfig);
|
||||
void dispatchAppVisibility(boolean visible);
|
||||
void dispatchGetNewSurface();
|
||||
void dispatchScreenStatus(boolean on);
|
||||
|
||||
/**
|
||||
* Tell the window that it is either gaining or losing focus. Keep it up
|
||||
|
||||
@@ -14845,6 +14845,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
|
||||
boolean mHardwareAccelerationRequested;
|
||||
HardwareRenderer mHardwareRenderer;
|
||||
|
||||
boolean mScreenOn;
|
||||
|
||||
/**
|
||||
* Scale factor used by the compatibility mode
|
||||
*/
|
||||
|
||||
@@ -46,6 +46,7 @@ import android.os.LatencyTimer;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
@@ -390,6 +391,9 @@ public final class ViewRootImpl implements ViewParent,
|
||||
mProfileRendering = Boolean.parseBoolean(
|
||||
SystemProperties.get(PROPERTY_PROFILE_RENDERING, "false"));
|
||||
mChoreographer = Choreographer.getInstance();
|
||||
|
||||
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
mAttachInfo.mScreenOn = powerManager.isScreenOn();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -757,6 +761,16 @@ public final class ViewRootImpl implements ViewParent,
|
||||
scheduleTraversals();
|
||||
}
|
||||
|
||||
void handleScreenStatusChange(boolean on) {
|
||||
if (on != mAttachInfo.mScreenOn) {
|
||||
mAttachInfo.mScreenOn = on;
|
||||
if (on) {
|
||||
mFullRedrawNeeded = true;
|
||||
scheduleTraversals();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -1886,6 +1900,8 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
private void performDraw() {
|
||||
if (!mAttachInfo.mScreenOn) return;
|
||||
|
||||
final long drawStartTime;
|
||||
if (ViewDebug.DEBUG_LATENCY) {
|
||||
drawStartTime = System.nanoTime();
|
||||
@@ -2018,8 +2034,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
if (!dirty.isEmpty() || mIsAnimating) {
|
||||
if (mAttachInfo.mHardwareRenderer != null
|
||||
&& mAttachInfo.mHardwareRenderer.isEnabled()) {
|
||||
if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
|
||||
// Draw with hardware renderer.
|
||||
mIsAnimating = false;
|
||||
mHardwareYOffset = yoff;
|
||||
@@ -2485,6 +2500,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID = 21;
|
||||
private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 22;
|
||||
private final static int MSG_PROCESS_INPUT_EVENTS = 23;
|
||||
private final static int MSG_DISPATCH_SCREEN_STATUS = 24;
|
||||
|
||||
final class ViewRootHandler extends Handler {
|
||||
@Override
|
||||
@@ -2741,6 +2757,11 @@ public final class ViewRootImpl implements ViewParent,
|
||||
.findAccessibilityNodeInfosByTextUiThread(msg);
|
||||
}
|
||||
} break;
|
||||
case MSG_DISPATCH_SCREEN_STATUS: {
|
||||
if (mView != null) {
|
||||
handleScreenStatusChange(msg.arg1 == 1);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4025,6 +4046,12 @@ public final class ViewRootImpl implements ViewParent,
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
public void dispatchScreenStatusChange(boolean on) {
|
||||
Message msg = mHandler.obtainMessage(MSG_DISPATCH_SCREEN_STATUS);
|
||||
msg.arg1 = on ? 1 : 0;
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
public void dispatchGetNewSurface() {
|
||||
Message msg = mHandler.obtainMessage(MSG_DISPATCH_GET_NEW_SURFACE);
|
||||
mHandler.sendMessage(msg);
|
||||
@@ -4226,6 +4253,13 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchScreenStatus(boolean on) {
|
||||
final ViewRootImpl viewAncestor = mViewAncestor.get();
|
||||
if (viewAncestor != null) {
|
||||
viewAncestor.dispatchScreenStatusChange(on);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchGetNewSurface() {
|
||||
final ViewRootImpl viewAncestor = mViewAncestor.get();
|
||||
if (viewAncestor != null) {
|
||||
|
||||
@@ -49,6 +49,9 @@ public class BaseIWindow extends IWindow.Stub {
|
||||
public void dispatchGetNewSurface() {
|
||||
}
|
||||
|
||||
public void dispatchScreenStatus(boolean on) {
|
||||
}
|
||||
|
||||
public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user