diff options
Diffstat (limited to 'services/java')
-rw-r--r-- | services/java/com/android/server/PowerManagerService.java | 51 | ||||
-rw-r--r-- | services/java/com/android/server/wm/WindowManagerService.java | 107 |
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"); |