summaryrefslogtreecommitdiffstats
path: root/services/java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java')
-rw-r--r--services/java/com/android/server/PowerManagerService.java51
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java107
2 files changed, 112 insertions, 46 deletions
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index bb21d81..0934cd0 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -161,7 +161,7 @@ public class PowerManagerService extends IPowerManager.Stub
private int mStayOnConditions = 0;
private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
private final int[] mBroadcastWhy = new int[3];
- private boolean mBroadcastingScreenOff = false;
+ private boolean mPreparingForScreenOn = false;
private int mPartialCount = 0;
private int mPowerState;
// mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
@@ -1122,7 +1122,8 @@ public class PowerManagerService extends IPowerManager.Stub
pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now
+ " " + ((mNextTimeout-now)/1000) + "s from now");
pw.println(" mDimScreen=" + mDimScreen
- + " mStayOnConditions=" + mStayOnConditions);
+ + " mStayOnConditions=" + mStayOnConditions
+ + " mPreparingForScreenOn=" + mPreparingForScreenOn);
pw.println(" mScreenOffReason=" + mScreenOffReason
+ " mUserState=" + mUserState);
pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
@@ -1341,7 +1342,9 @@ public class PowerManagerService extends IPowerManager.Stub
mBroadcastQueue[0] = on ? 1 : 0;
mBroadcastQueue[1] = -1;
mBroadcastQueue[2] = -1;
+ EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
mBroadcastWakeLock.release();
+ EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
mBroadcastWakeLock.release();
index = 0;
}
@@ -1371,6 +1374,21 @@ public class PowerManagerService extends IPowerManager.Stub
}
}
+ private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
+ new WindowManagerPolicy.ScreenOnListener() {
+ @Override public void onScreenOn() {
+ synchronized (mLocks) {
+ if (mPreparingForScreenOn) {
+ mPreparingForScreenOn = false;
+ updateNativePowerStateLocked();
+ EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
+ 4, mBroadcastWakeLock.mCount);
+ mBroadcastWakeLock.release();
+ }
+ }
+ }
+ };
+
private Runnable mNotificationTask = new Runnable()
{
public void run()
@@ -1387,14 +1405,17 @@ public class PowerManagerService extends IPowerManager.Stub
mBroadcastWhy[i] = mBroadcastWhy[i+1];
}
policy = getPolicyLocked();
- if (value == 0) {
- mBroadcastingScreenOff = true;
+ if (value == 1 && !mPreparingForScreenOn) {
+ mPreparingForScreenOn = true;
+ mBroadcastWakeLock.acquire();
+ EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
+ mBroadcastWakeLock.mCount);
}
}
if (value == 1) {
mScreenOnStart = SystemClock.uptimeMillis();
- policy.screenTurnedOn();
+ policy.screenTurningOn(mScreenOnListener);
try {
ActivityManagerNative.getDefault().wakingUp();
} catch (RemoteException e) {
@@ -1432,7 +1453,6 @@ public class PowerManagerService extends IPowerManager.Stub
synchronized (mLocks) {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
mBroadcastWakeLock.mCount);
- mBroadcastingScreenOff = false;
updateNativePowerStateLocked();
mBroadcastWakeLock.release();
}
@@ -1464,10 +1484,6 @@ public class PowerManagerService extends IPowerManager.Stub
synchronized (mLocks) {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
- synchronized (mLocks) {
- mBroadcastingScreenOff = false;
- updateNativePowerStateLocked();
- }
mBroadcastWakeLock.release();
}
}
@@ -1795,17 +1811,18 @@ public class PowerManagerService extends IPowerManager.Stub
private void updateNativePowerStateLocked() {
if ((mPowerState & SCREEN_ON_BIT) != 0) {
- // Don't turn screen on if we are currently reporting a screen off.
+ // Don't turn screen on until we know we are really ready to.
// This is to avoid letting the screen go on before things like the
- // lock screen have been displayed due to it going off.
- if (mBroadcastingScreenOff) {
- // Currently broadcasting that the screen is off. Don't
- // allow screen to go on until that is done.
+ // lock screen have been displayed.
+ if (mPreparingForScreenOn) {
+ // Currently waiting for confirmation from the policy that it
+ // is okay to turn on the screen. Don't allow the screen to go
+ // on until that is done.
return;
}
for (int i=0; i<mBroadcastQueue.length; i++) {
- if (mBroadcastQueue[i] == 0) {
- // A screen off is currently enqueued.
+ if (mBroadcastQueue[i] == 1) {
+ // A screen on is currently enqueued.
return;
}
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 609016b..755a8b8 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -73,6 +73,7 @@ import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IRemoteCallback;
import android.os.LocalPowerManager;
import android.os.Looper;
import android.os.Message;
@@ -91,6 +92,7 @@ import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseIntArray;
import android.util.TypedValue;
@@ -384,6 +386,12 @@ public class WindowManagerService extends IWindowManager.Stub
ArrayList<WindowState> mForceRemoves;
/**
+ * Windows that clients are waiting to have drawn.
+ */
+ ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
+ = new ArrayList<Pair<WindowState, IRemoteCallback>>();
+
+ /**
* Used when rebuilding window list to keep track of windows that have
* been removed.
*/
@@ -6295,6 +6303,7 @@ public class WindowManagerService extends IWindowManager.Stub
public static final int DRAG_END_TIMEOUT = 21;
public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
public static final int BOOT_TIMEOUT = 23;
+ public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
private Session mLastReportedHold;
@@ -6605,11 +6614,6 @@ public class WindowManagerService extends IWindowManager.Stub
break;
}
- case BOOT_TIMEOUT: {
- performBootTimeout();
- break;
- }
-
case APP_FREEZE_TIMEOUT: {
synchronized (mWindowMap) {
Slog.w(TAG, "App freeze timeout expired.");
@@ -6678,6 +6682,27 @@ public class WindowManagerService extends IWindowManager.Stub
notifyHardKeyboardStatusChange();
break;
}
+
+ case BOOT_TIMEOUT: {
+ performBootTimeout();
+ break;
+ }
+
+ case WAITING_FOR_DRAWN_TIMEOUT: {
+ Pair<WindowState, IRemoteCallback> pair;
+ synchronized (mWindowMap) {
+ pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
+ Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
+ if (!mWaitingForDrawn.remove(pair)) {
+ return;
+ }
+ }
+ try {
+ pair.second.sendResult(null);
+ } catch (RemoteException e) {
+ }
+ break;
+ }
}
}
}
@@ -8582,43 +8607,58 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- mWindowMap.notifyAll();
+ checkDrawnWindowsLocked();
// Check to see if we are now in a state where the screen should
// be enabled, because the window obscured flags have changed.
enableScreenIfNeededLocked();
}
- public void waitForAllDrawn() {
- synchronized (mWindowMap) {
- while (true) {
- final int N = mWindows.size();
- boolean okay = true;
- for (int i=0; i<N && okay; i++) {
- WindowState w = mWindows.get(i);
- if (DEBUG_SCREEN_ON) {
- Slog.i(TAG, "Window " + w + " vis=" + w.isVisibleLw()
- + " obscured=" + w.mObscured + " drawn=" + w.isDrawnLw());
+ void checkDrawnWindowsLocked() {
+ if (mWaitingForDrawn.size() > 0) {
+ for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
+ Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
+ WindowState win = pair.first;
+ //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
+ // + win.mRemoved + " visible=" + win.isVisibleLw()
+ // + " shown=" + win.mSurfaceShown);
+ if (win.mRemoved || !win.isVisibleLw()) {
+ // Window has been removed or made invisible; no draw
+ // will now happen, so stop waiting.
+ Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
+ try {
+ pair.second.sendResult(null);
+ } catch (RemoteException e) {
}
- if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
- if (DEBUG_SCREEN_ON) {
- Slog.i(TAG, "Window not yet drawn: " + w);
- }
- okay = false;
- break;
+ mWaitingForDrawn.remove(pair);
+ mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
+ } else if (win.mSurfaceShown) {
+ // Window is now drawn (and shown).
+ try {
+ pair.second.sendResult(null);
+ } catch (RemoteException e) {
}
- }
- if (okay) {
- return;
- }
- try {
- mWindowMap.wait();
- } catch (InterruptedException e) {
+ mWaitingForDrawn.remove(pair);
+ mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
}
}
}
}
+ public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
+ synchronized (mWindowMap) {
+ WindowState win = windowForClientLocked(null, token, true);
+ if (win != null) {
+ Pair<WindowState, IRemoteCallback> pair =
+ new Pair<WindowState, IRemoteCallback>(win, callback);
+ Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
+ mH.sendMessageDelayed(m, 2000);
+ mWaitingForDrawn.add(pair);
+ checkDrawnWindowsLocked();
+ }
+ }
+ }
+
/**
* Must be called with the main window manager lock held.
*/
@@ -9284,6 +9324,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
+ if (mWaitingForDrawn.size() > 0) {
+ pw.println();
+ pw.println(" Clients waiting for these windows to be drawn:");
+ for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
+ Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
+ pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
+ pw.print(": "); pw.println(pair.second);
+ }
+ }
pw.println();
if (mDisplay != null) {
pw.print(" Display: init="); pw.print(mInitialDisplayWidth); pw.print("x");