summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp24
-rw-r--r--services/java/com/android/server/PowerManagerService.java32
-rw-r--r--services/java/com/android/server/wm/Session.java8
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java59
-rw-r--r--services/java/com/android/server/wm/WindowState.java74
5 files changed, 166 insertions, 31 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 780c0d2..aea31a8 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -89,6 +89,12 @@ static const int kRecordThreadSleepUs = 5000;
static const nsecs_t kSetParametersTimeout = seconds(2);
+// minimum sleep time for the mixer thread loop when tracks are active but in underrun
+static const uint32_t kMinThreadSleepTimeUs = 5000;
+// maximum divider applied to the active sleep time in the mixer thread loop
+static const uint32_t kMaxThreadSleepTimeShift = 2;
+
+
// ----------------------------------------------------------------------------
static bool recordingAllowed() {
@@ -1846,6 +1852,7 @@ bool AudioFlinger::MixerThread::threadLoop()
uint32_t activeSleepTime = activeSleepTimeUs();
uint32_t idleSleepTime = idleSleepTimeUs();
uint32_t sleepTime = idleSleepTime;
+ uint32_t sleepTimeShift = 0;
Vector< sp<EffectChain> > effectChains;
#ifdef DEBUG_CPU_USAGE
ThreadCpuUsage cpu;
@@ -1937,6 +1944,7 @@ bool AudioFlinger::MixerThread::threadLoop()
standbyTime = systemTime() + kStandbyTimeInNsecs;
sleepTime = idleSleepTime;
+ sleepTimeShift = 0;
continue;
}
}
@@ -1953,6 +1961,10 @@ bool AudioFlinger::MixerThread::threadLoop()
// mix buffers...
mAudioMixer->process();
sleepTime = 0;
+ // increase sleep time progressively when application underrun condition clears
+ if (sleepTimeShift > 0) {
+ sleepTimeShift--;
+ }
standbyTime = systemTime() + kStandbyTimeInNsecs;
//TODO: delay standby when effects have a tail
} else {
@@ -1960,7 +1972,17 @@ bool AudioFlinger::MixerThread::threadLoop()
// buffer size, then write 0s to the output
if (sleepTime == 0) {
if (mixerStatus == MIXER_TRACKS_ENABLED) {
- sleepTime = activeSleepTime;
+ sleepTime = activeSleepTime >> sleepTimeShift;
+ if (sleepTime < kMinThreadSleepTimeUs) {
+ sleepTime = kMinThreadSleepTimeUs;
+ }
+ // reduce sleep time in case of consecutive application underruns to avoid
+ // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer
+ // duration we would end up writing less data than needed by the audio HAL if
+ // the condition persists.
+ if (sleepTimeShift < kMaxThreadSleepTimeShift) {
+ sleepTimeShift++;
+ }
} else {
sleepTime = idleSleepTime;
}
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 6b23b33..2a0d2a0 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1689,6 +1689,11 @@ public class PowerManagerService extends IPowerManager.Stub
// before showing it to the user. We want the light off
// until it is ready to be shown to the user, not it using
// whatever the last value it had.
+ if (DEBUG_SCREEN_ON) {
+ Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
+ + Integer.toHexString(mPowerState)
+ + " mSkippedScreenOn=" + mSkippedScreenOn);
+ }
mScreenBrightness.forceValueLocked(Power.BRIGHTNESS_OFF);
}
}
@@ -2038,12 +2043,14 @@ public class PowerManagerService extends IPowerManager.Stub
} finally {
Binder.restoreCallingIdentity(identity);
}
- mScreenBrightness.setTargetLocked(brightness, steps,
- INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
- if (DEBUG_SCREEN_ON) {
- RuntimeException e = new RuntimeException("here");
- e.fillInStackTrace();
- Slog.i(TAG, "Setting screen brightness: " + brightness, e);
+ if (!mSkippedScreenOn) {
+ mScreenBrightness.setTargetLocked(brightness, steps,
+ INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
+ if (DEBUG_SCREEN_ON) {
+ RuntimeException e = new RuntimeException("here");
+ e.fillInStackTrace();
+ Slog.i(TAG, "Setting screen brightness: " + brightness, e);
+ }
}
}
@@ -2086,6 +2093,11 @@ public class PowerManagerService extends IPowerManager.Stub
? LightsService.BRIGHTNESS_MODE_SENSOR
: LightsService.BRIGHTNESS_MODE_USER);
if ((mask & SCREEN_BRIGHT_BIT) != 0) {
+ if (DEBUG_SCREEN_ON) {
+ RuntimeException e = new RuntimeException("here");
+ e.fillInStackTrace();
+ Slog.i(TAG, "Set LCD brightness: " + value, e);
+ }
mLcdLight.setBrightness(value, brightnessMode);
}
if ((mask & BUTTON_BRIGHT_BIT) != 0) {
@@ -2137,7 +2149,7 @@ public class PowerManagerService extends IPowerManager.Stub
delta = (targetValue -
(nominalCurrentValue >= 0 ? nominalCurrentValue : curValue))
/ stepsToTarget;
- if (mSpew) {
+ if (mSpew || DEBUG_SCREEN_ON) {
String noticeMe = nominalCurrentValue == curValue ? "" : " ******************";
Slog.i(TAG, "setTargetLocked mask=" + mask + " curValue=" + curValue
+ " target=" + target + " targetValue=" + targetValue + " delta=" + delta
@@ -2527,8 +2539,10 @@ public class PowerManagerService extends IPowerManager.Stub
}
if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
- mScreenBrightness.setTargetLocked(lcdValue, AUTOBRIGHTNESS_ANIM_STEPS,
- INITIAL_SCREEN_BRIGHTNESS, (int)mScreenBrightness.curValue);
+ if (!mSkippedScreenOn) {
+ mScreenBrightness.setTargetLocked(lcdValue, AUTOBRIGHTNESS_ANIM_STEPS,
+ INITIAL_SCREEN_BRIGHTNESS, (int)mScreenBrightness.curValue);
+ }
}
if (mButtonBrightnessOverride < 0) {
mButtonLight.setBrightness(buttonValue);
diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java
index ee62a56..77575f2 100644
--- a/services/java/com/android/server/wm/Session.java
+++ b/services/java/com/android/server/wm/Session.java
@@ -151,18 +151,22 @@ final class Session extends IWindowSession.Stub
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
- boolean insetsPending, Rect outFrame, Rect outContentInsets,
+ int flags, Rect outFrame, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from "
+ Binder.getCallingPid());
int res = mService.relayoutWindow(this, window, seq, attrs,
- requestedWidth, requestedHeight, viewFlags, insetsPending,
+ requestedWidth, requestedHeight, viewFlags, flags,
outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;
}
+ public void performDeferredDestroy(IWindow window) {
+ mService.performDeferredDestroyWindow(this, window);
+ }
+
public boolean outOfMemory(IWindow window) {
return mService.outOfMemoryWindow(this, window);
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index ebb13d5..769e6cf 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -2499,12 +2499,13 @@ public class WindowManagerService extends IWindowManager.Stub
public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
- int requestedHeight, int viewVisibility, boolean insetsPending,
+ int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Configuration outConfig, Surface outSurface) {
boolean displayed = false;
boolean inTouchMode;
boolean configChanged;
+ boolean surfaceChanged = false;
// if they don't have this permission, mask out the status bar bits
int systemUiVisibility = 0;
@@ -2534,6 +2535,9 @@ public class WindowManagerService extends IWindowManager.Stub
mPolicy.adjustWindowParamsLw(attrs);
}
+ win.mSurfaceDestroyDeferred =
+ (flags&WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
+
int attrChanges = 0;
int flagChanges = 0;
if (attrs != null) {
@@ -2630,8 +2634,12 @@ public class WindowManagerService extends IWindowManager.Stub
// To change the format, we need to re-build the surface.
win.destroySurfaceLocked();
displayed = true;
+ surfaceChanged = true;
}
try {
+ if (win.mSurface == null) {
+ surfaceChanged = true;
+ }
Surface surface = win.createSurfaceLocked();
if (surface != null) {
outSurface.copyFrom(surface);
@@ -2683,6 +2691,7 @@ public class WindowManagerService extends IWindowManager.Stub
// If we are not currently running the exit animation, we
// need to see about starting one.
if (!win.mExiting || win.mSurfacePendingDestroy) {
+ surfaceChanged = true;
// Try starting an animation; if there isn't one, we
// can destroy the surface right away.
int transit = WindowManagerPolicy.TRANSIT_EXIT;
@@ -2715,10 +2724,10 @@ public class WindowManagerService extends IWindowManager.Stub
if (win.mSurface == null || (win.getAttrs().flags
& WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
|| win.mSurfacePendingDestroy) {
- // We are being called from a local process, which
+ // We could be called from a local process, which
// means outSurface holds its current surface. Ensure the
- // surface object is cleared, but we don't want it actually
- // destroyed at this point.
+ // surface object is cleared, but we don't necessarily want
+ // it actually destroyed at this point.
win.mSurfacePendingDestroy = false;
outSurface.release();
if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
@@ -2760,7 +2769,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
mLayoutNeeded = true;
- win.mGivenInsetsPending = insetsPending;
+ win.mGivenInsetsPending = (flags&WindowManagerImpl.RELAYOUT_INSETS_PENDING) != 0;
if (assignLayers) {
assignLayersLocked();
}
@@ -2797,8 +2806,25 @@ public class WindowManagerService extends IWindowManager.Stub
Binder.restoreCallingIdentity(origId);
- return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
- | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
+ return (inTouchMode ? WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE : 0)
+ | (displayed ? WindowManagerImpl.RELAYOUT_RES_FIRST_TIME : 0)
+ | (surfaceChanged ? WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED : 0);
+ }
+
+ public void performDeferredDestroyWindow(Session session, IWindow client) {
+ long origId = Binder.clearCallingIdentity();
+
+ try {
+ synchronized(mWindowMap) {
+ WindowState win = windowForClientLocked(session, client, false);
+ if (win == null) {
+ return;
+ }
+ win.destroyDeferredSurfaceLocked();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
}
public boolean outOfMemoryWindow(Session session, IWindow client) {
@@ -3738,7 +3764,7 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
- // If this is a translucent or wallpaper window, then don't
+ // If this is a translucent window, then don't
// show a starting window -- the current effect (a full-screen
// opaque starting window that fades away to the real contents
// when it is ready) does not work for this.
@@ -3755,7 +3781,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
- return;
+ if (mWallpaperTarget == null) {
+ // If this theme is requesting a wallpaper, and the wallpaper
+ // is not curently visible, then this effectively serves as
+ // an opaque window and our starting window transition animation
+ // can still work. We just need to make sure the starting window
+ // is also showing the wallpaper.
+ windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+ } else {
+ return;
+ }
}
}
@@ -7659,7 +7694,8 @@ public class WindowManagerService extends IWindowManager.Stub
// a detached wallpaper animation.
if (nowAnimating) {
if (w.mAnimation != null) {
- if (w.mAnimation.getDetachWallpaper()) {
+ if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
+ && w.mAnimation.getDetachWallpaper()) {
windowDetachedWallpaper = w;
}
if (w.mAnimation.getBackgroundColor() != 0) {
@@ -7679,7 +7715,8 @@ public class WindowManagerService extends IWindowManager.Stub
// displayed behind it.
if (w.mAppToken != null && w.mAppToken.animation != null
&& w.mAppToken.animating) {
- if (w.mAppToken.animation.getDetachWallpaper()) {
+ if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
+ && w.mAppToken.animation.getDetachWallpaper()) {
windowDetachedWallpaper = w;
}
if (w.mAppToken.animation.getBackgroundColor() != 0) {
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 23ec2d9..aa7bf2d 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -85,6 +85,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mPolicyVisibilityAfterAnim = true;
boolean mAppFreezing;
Surface mSurface;
+ Surface mPendingDestroySurface;
boolean mReportDestroySurface;
boolean mSurfacePendingDestroy;
boolean mAttachedHidden; // is our parent window hidden?
@@ -121,7 +122,13 @@ final class WindowState implements WindowManagerPolicy.WindowState {
* we must tell them application to resize (and thus redraw itself).
*/
boolean mSurfaceResized;
-
+
+ /**
+ * Set if the client has asked that the destroy of its surface be delayed
+ * until it explicitly says it is okay.
+ */
+ boolean mSurfaceDestroyDeferred;
+
/**
* Insets that determine the actually visible area. These are in the application's
* coordinate space (without compatibility scale applied).
@@ -764,15 +771,32 @@ final class WindowState implements WindowManagerPolicy.WindowState {
Slog.w(WindowManagerService.TAG, "Window " + this + " destroying surface "
+ mSurface + ", session " + mSession, e);
}
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
- RuntimeException e = null;
- if (!WindowManagerService.HIDE_STACK_CRAWLS) {
- e = new RuntimeException();
- e.fillInStackTrace();
+ if (mSurfaceDestroyDeferred) {
+ if (mSurface != null && mPendingDestroySurface != mSurface) {
+ if (mPendingDestroySurface != null) {
+ if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+ RuntimeException e = null;
+ if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ WindowManagerService.logSurface(this, "DESTROY PENDING", e);
+ }
+ mPendingDestroySurface.destroy();
+ }
+ mPendingDestroySurface = mSurface;
}
- WindowManagerService.logSurface(this, "DESTROY", e);
+ } else {
+ if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+ RuntimeException e = null;
+ if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ WindowManagerService.logSurface(this, "DESTROY", e);
+ }
+ mSurface.destroy();
}
- mSurface.destroy();
} catch (RuntimeException e) {
Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window " + this
+ " surface " + mSurface + " session " + mSession
@@ -784,6 +808,28 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
}
+ void destroyDeferredSurfaceLocked() {
+ try {
+ if (mPendingDestroySurface != null) {
+ if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+ RuntimeException e = null;
+ if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ mService.logSurface(this, "DESTROY PENDING", e);
+ }
+ mPendingDestroySurface.destroy();
+ }
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window "
+ + this + " surface " + mPendingDestroySurface
+ + " session " + mSession + ": " + e.toString());
+ }
+ mSurfaceDestroyDeferred = false;
+ mPendingDestroySurface = null;
+ }
+
boolean finishDrawingLocked() {
if (mDrawPending) {
if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) Slog.v(
@@ -977,6 +1023,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mAnimation.cancel();
mAnimation = null;
}
+ if (mService.mWindowDetachedWallpaper == this) {
+ mService.mWindowDetachedWallpaper = null;
+ }
mAnimLayer = mLayer;
if (mIsImWindow) {
mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
@@ -1415,6 +1464,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Removing " + this + " from " + mAttachedWindow);
mAttachedWindow.mChildWindows.remove(this);
}
+ destroyDeferredSurfaceLocked();
destroySurfaceLocked();
mSession.windowRemovedLocked();
try {
@@ -1612,6 +1662,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.print(") "); pw.print(mSurfaceW);
pw.print(" x "); pw.println(mSurfaceH);
}
+ if (mPendingDestroySurface != null) {
+ pw.print(prefix); pw.print("mPendingDestroySurface=");
+ pw.println(mPendingDestroySurface);
+ }
if (dumpAll) {
pw.print(prefix); pw.print("mToken="); pw.println(mToken);
pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
@@ -1640,6 +1694,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (!mRelayoutCalled) {
pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
}
+ if (mSurfaceResized || mSurfaceDestroyDeferred) {
+ pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
+ pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
+ }
if (mXOffset != 0 || mYOffset != 0) {
pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
pw.print(" y="); pw.println(mYOffset);