Split stacks and move tasks between them. Layout the windows according to the new stack split. After layout content rectangles are known split the available area between all stack boxes. Then use those values for future layout. Provide stack contents to ActivityManager. Change-Id: I9746e6185445633810d506be514d0b7b540a7f99
270 lines
9.3 KiB
Java
270 lines
9.3 KiB
Java
// Copyright 2012 Google Inc. All Rights Reserved.
|
|
|
|
package com.android.server.wm;
|
|
|
|
import android.graphics.PixelFormat;
|
|
import android.os.SystemClock;
|
|
import android.util.Slog;
|
|
import android.view.DisplayInfo;
|
|
import android.view.SurfaceControl;
|
|
|
|
import java.io.PrintWriter;
|
|
|
|
public class DimLayer {
|
|
private static final String TAG = "DimLayer";
|
|
private static final boolean DEBUG = false;
|
|
|
|
/** Reference to the owner of this object. */
|
|
final DisplayContent mDisplayContent;
|
|
|
|
/** Actual surface that dims */
|
|
SurfaceControl mDimSurface;
|
|
|
|
/** Last value passed to mDimSurface.setAlpha() */
|
|
float mAlpha = 0;
|
|
|
|
/** Last value passed to mDimSurface.setLayer() */
|
|
int mLayer = -1;
|
|
|
|
/** Last values passed to mDimSurface.setSize() */
|
|
int mLastDimWidth, mLastDimHeight;
|
|
|
|
/** True after mDimSurface.show() has been called, false after mDimSurface.hide(). */
|
|
private boolean mShowing = false;
|
|
|
|
/** Value of mAlpha when beginning transition to mTargetAlpha */
|
|
float mStartAlpha = 0;
|
|
|
|
/** Final value of mAlpha following transition */
|
|
float mTargetAlpha = 0;
|
|
|
|
/** Time in units of SystemClock.uptimeMillis() at which the current transition started */
|
|
long mStartTime;
|
|
|
|
/** Time in milliseconds to take to transition from mStartAlpha to mTargetAlpha */
|
|
long mDuration;
|
|
|
|
DimLayer(WindowManagerService service, int displayId) {
|
|
if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);
|
|
mDisplayContent = service.getDisplayContentLocked(displayId);
|
|
SurfaceControl.openTransaction();
|
|
try {
|
|
if (WindowManagerService.DEBUG_SURFACE_TRACE) {
|
|
mDimSurface = new WindowStateAnimator.SurfaceTrace(service.mFxSession,
|
|
"DimSurface",
|
|
16, 16, PixelFormat.OPAQUE,
|
|
SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
|
|
} else {
|
|
mDimSurface = new SurfaceControl(service.mFxSession, TAG,
|
|
16, 16, PixelFormat.OPAQUE,
|
|
SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
|
|
}
|
|
if (WindowManagerService.SHOW_TRANSACTIONS ||
|
|
WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(TAG,
|
|
" DIM " + mDimSurface + ": CREATE");
|
|
mDimSurface.setLayerStack(displayId);
|
|
} catch (Exception e) {
|
|
Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e);
|
|
} finally {
|
|
SurfaceControl.closeTransaction();
|
|
}
|
|
}
|
|
|
|
/** Return true if dim layer is showing */
|
|
boolean isDimming() {
|
|
return mTargetAlpha != 0;
|
|
}
|
|
|
|
/** Return true if in a transition period */
|
|
boolean isAnimating() {
|
|
return mTargetAlpha != mAlpha;
|
|
}
|
|
|
|
float getTargetAlpha() {
|
|
return mTargetAlpha;
|
|
}
|
|
|
|
void setLayer(int layer) {
|
|
if (mLayer != layer) {
|
|
mLayer = layer;
|
|
mDimSurface.setLayer(layer);
|
|
}
|
|
}
|
|
|
|
int getLayer() {
|
|
return mLayer;
|
|
}
|
|
|
|
private void setAlpha(float alpha) {
|
|
if (mAlpha != alpha) {
|
|
if (DEBUG) Slog.v(TAG, "setAlpha alpha=" + alpha);
|
|
try {
|
|
mDimSurface.setAlpha(alpha);
|
|
if (alpha == 0 && mShowing) {
|
|
if (DEBUG) Slog.v(TAG, "setAlpha hiding");
|
|
mDimSurface.hide();
|
|
mShowing = false;
|
|
} else if (alpha > 0 && !mShowing) {
|
|
if (DEBUG) Slog.v(TAG, "setAlpha showing");
|
|
mDimSurface.show();
|
|
mShowing = true;
|
|
}
|
|
} catch (RuntimeException e) {
|
|
Slog.w(TAG, "Failure setting alpha immediately", e);
|
|
}
|
|
mAlpha = alpha;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param duration The time to test.
|
|
* @return True if the duration would lead to an earlier end to the current animation.
|
|
*/
|
|
private boolean durationEndsEarlier(long duration) {
|
|
return SystemClock.uptimeMillis() + duration < mStartTime + mDuration;
|
|
}
|
|
|
|
/** Jump to the end of the animation.
|
|
* NOTE: Must be called with Surface transaction open. */
|
|
void show() {
|
|
if (isAnimating()) {
|
|
if (DEBUG) Slog.v(TAG, "show: immediate");
|
|
show(mLayer, mTargetAlpha, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Begin an animation to a new dim value.
|
|
* NOTE: Must be called with Surface transaction open.
|
|
*
|
|
* @param layer The layer to set the surface to.
|
|
* @param alpha The dim value to end at.
|
|
* @param duration How long to take to get there in milliseconds.
|
|
*/
|
|
void show(int layer, float alpha, long duration) {
|
|
if (DEBUG) Slog.v(TAG, "show: layer=" + layer + " alpha=" + alpha
|
|
+ " duration=" + duration);
|
|
if (mDimSurface == null) {
|
|
Slog.e(TAG, "show: no Surface");
|
|
// Make sure isAnimating() returns false.
|
|
mTargetAlpha = mAlpha = 0;
|
|
return;
|
|
}
|
|
|
|
// Set surface size to screen size.
|
|
final DisplayInfo info = mDisplayContent.getDisplayInfo();
|
|
// Multiply by 1.5 so that rotating a frozen surface that includes this does not expose a
|
|
// corner.
|
|
final int dw = (int) (info.logicalWidth * 1.5);
|
|
final int dh = (int) (info.logicalHeight * 1.5);
|
|
// back off position so 1/4 of Surface is before and 1/4 is after.
|
|
final float xPos = -1 * dw / 6;
|
|
final float yPos = -1 * dh / 6;
|
|
|
|
if (mLastDimWidth != dw || mLastDimHeight != dh || mLayer != layer) {
|
|
try {
|
|
mDimSurface.setPosition(xPos, yPos);
|
|
mDimSurface.setSize(dw, dh);
|
|
mDimSurface.setLayer(layer);
|
|
} catch (RuntimeException e) {
|
|
Slog.w(TAG, "Failure setting size or layer", e);
|
|
}
|
|
mLastDimWidth = dw;
|
|
mLastDimHeight = dh;
|
|
mLayer = layer;
|
|
}
|
|
|
|
long curTime = SystemClock.uptimeMillis();
|
|
final boolean animating = isAnimating();
|
|
if ((animating && (mTargetAlpha != alpha || durationEndsEarlier(duration)))
|
|
|| (!animating && mAlpha != alpha)) {
|
|
if (duration <= 0) {
|
|
// No animation required, just set values.
|
|
setAlpha(alpha);
|
|
} else {
|
|
// Start or continue animation with new parameters.
|
|
mStartAlpha = mAlpha;
|
|
mStartTime = curTime;
|
|
mDuration = duration;
|
|
}
|
|
}
|
|
if (DEBUG) Slog.v(TAG, "show: mStartAlpha=" + mStartAlpha + " mStartTime=" + mStartTime);
|
|
mTargetAlpha = alpha;
|
|
}
|
|
|
|
/** Immediate hide.
|
|
* NOTE: Must be called with Surface transaction open. */
|
|
void hide() {
|
|
if (mShowing) {
|
|
if (DEBUG) Slog.v(TAG, "hide: immediate");
|
|
hide(0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gradually fade to transparent.
|
|
* NOTE: Must be called with Surface transaction open.
|
|
*
|
|
* @param duration Time to fade in milliseconds.
|
|
*/
|
|
void hide(long duration) {
|
|
if (mShowing && (mTargetAlpha != 0 || durationEndsEarlier(duration))) {
|
|
if (DEBUG) Slog.v(TAG, "hide: duration=" + duration);
|
|
show(mLayer, 0, duration);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Advance the dimming per the last #show(int, float, long) call.
|
|
* NOTE: Must be called with Surface transaction open.
|
|
*
|
|
* @return True if animation is still required after this step.
|
|
*/
|
|
boolean stepAnimation() {
|
|
if (mDimSurface == null) {
|
|
Slog.e(TAG, "stepAnimation: null Surface");
|
|
// Ensure that isAnimating() returns false;
|
|
mTargetAlpha = mAlpha = 0;
|
|
return false;
|
|
}
|
|
|
|
if (isAnimating()) {
|
|
final long curTime = SystemClock.uptimeMillis();
|
|
final float alphaDelta = mTargetAlpha - mStartAlpha;
|
|
float alpha = mStartAlpha + alphaDelta * (curTime - mStartTime) / mDuration;
|
|
if (alphaDelta > 0 && alpha > mTargetAlpha ||
|
|
alphaDelta < 0 && alpha < mTargetAlpha) {
|
|
// Don't exceed limits.
|
|
alpha = mTargetAlpha;
|
|
}
|
|
if (DEBUG) Slog.v(TAG, "stepAnimation: curTime=" + curTime + " alpha=" + alpha);
|
|
setAlpha(alpha);
|
|
}
|
|
|
|
return isAnimating();
|
|
}
|
|
|
|
/** Cleanup */
|
|
void destroySurface() {
|
|
if (DEBUG) Slog.v(TAG, "destroySurface.");
|
|
if (mDimSurface != null) {
|
|
mDimSurface.destroy();
|
|
mDimSurface = null;
|
|
}
|
|
}
|
|
|
|
public void printTo(String prefix, PrintWriter pw) {
|
|
pw.print(prefix); pw.print("mDimSurface="); pw.print(mDimSurface);
|
|
pw.print(" mLayer="); pw.print(mLayer);
|
|
pw.print(" mAlpha="); pw.println(mAlpha);
|
|
pw.print(prefix); pw.print("mLastDimWidth="); pw.print(mLastDimWidth);
|
|
pw.print(" mLastDimHeight="); pw.println(mLastDimHeight);
|
|
pw.print(prefix); pw.print("Last animation: ");
|
|
pw.print(" mDuration="); pw.print(mDuration);
|
|
pw.print(" mStartTime="); pw.print(mStartTime);
|
|
pw.print(" curTime="); pw.println(SystemClock.uptimeMillis());
|
|
pw.print(prefix); pw.print(" mStartAlpha="); pw.print(mStartAlpha);
|
|
pw.print(" mTargetAlpha="); pw.println(mTargetAlpha);
|
|
}
|
|
}
|