summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/wm
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java/com/android/server/wm')
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java9
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java208
-rw-r--r--services/core/java/com/android/server/wm/AppWindowAnimator.java27
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java33
-rw-r--r--services/core/java/com/android/server/wm/DimLayer.java15
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java35
-rw-r--r--services/core/java/com/android/server/wm/DragState.java8
-rw-r--r--services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java1
-rw-r--r--services/core/java/com/android/server/wm/FocusedStackFrame.java124
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java21
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java10
-rw-r--r--services/core/java/com/android/server/wm/Session.java14
-rw-r--r--services/core/java/com/android/server/wm/Task.java66
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java191
-rw-r--r--services/core/java/com/android/server/wm/Watermark.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowAnimator.java106
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java1261
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java143
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java77
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java3
20 files changed, 1325 insertions, 1029 deletions
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 37ca0db..91ce739 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -339,6 +339,7 @@ final class AccessibilityController {
case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL:
case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA:
case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL:
+ case WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL:
case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG:
case WindowManager.LayoutParams.TYPE_SEARCH_BAR:
case WindowManager.LayoutParams.TYPE_PHONE:
@@ -620,9 +621,8 @@ final class AccessibilityController {
final int windowCount = windowList.size();
for (int i = 0; i < windowCount; i++) {
WindowState windowState = windowList.get(i);
- if ((windowState.isOnScreen() || windowState.mAttrs.type == WindowManager
- .LayoutParams.TYPE_UNIVERSE_BACKGROUND)
- && !windowState.mWinAnimator.mEnterAnimationPending) {
+ if (windowState.isOnScreen() &&
+ !windowState.mWinAnimator.mEnterAnimationPending) {
outWindows.put(windowState.mLayer, windowState);
}
}
@@ -670,7 +670,7 @@ final class AccessibilityController {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight,
typedValue, true);
- final int borderColor = context.getResources().getColor(typedValue.resourceId);
+ final int borderColor = context.getColor(typedValue.resourceId);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mBorderWidth);
@@ -1251,7 +1251,6 @@ final class AccessibilityController {
&& windowType != WindowManager.LayoutParams.TYPE_DRAG
&& windowType != WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER
&& windowType != WindowManager.LayoutParams.TYPE_POINTER
- && windowType != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
&& windowType != WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY
&& windowType != WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
&& windowType != WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index c0d54e1..9033c9c 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -22,6 +22,7 @@ import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Debug;
import android.os.Handler;
+import android.os.IBinder;
import android.os.IRemoteCallback;
import android.util.Slog;
import android.view.WindowManager;
@@ -30,15 +31,22 @@ import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.ClipRectAnimation;
+import android.view.animation.ClipRectLRAnimation;
+import android.view.animation.ClipRectTBAnimation;
import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
+import android.view.animation.TranslateXAnimation;
+import android.view.animation.TranslateYAnimation;
import com.android.internal.util.DumpUtils.Dump;
import com.android.server.AttributeCache;
import com.android.server.wm.WindowManagerService.H;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import static android.view.WindowManagerInternal.AppTransitionListener;
import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation;
@@ -134,6 +142,7 @@ public class AppTransition implements Dump {
private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP = 5;
private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN = 6;
private static final int NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE = 7;
+ private static final int NEXT_TRANSIT_TYPE_CLIP_REVEAL = 8;
private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
// These are the possible states for the enter/exit activities during a thumbnail transition
@@ -169,19 +178,26 @@ public class AppTransition implements Dump {
private final Interpolator mDecelerateInterpolator;
private final Interpolator mThumbnailFadeInInterpolator;
private final Interpolator mThumbnailFadeOutInterpolator;
- private final Interpolator mThumbnailFastOutSlowInInterpolator;
+ private final Interpolator mLinearOutSlowInInterpolator;
+ private final Interpolator mFastOutSlowInInterpolator;
+ private final LinearInterpolator mLinearInterpolator;
private int mCurrentUserId = 0;
+ private final ArrayList<AppTransitionListener> mListeners = new ArrayList<>();
+
AppTransition(Context context, Handler h) {
mContext = context;
mH = h;
+ mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.linear_out_slow_in);
+ mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.fast_out_slow_in);
+ mLinearInterpolator = new LinearInterpolator();
mConfigShortAnimTime = context.getResources().getInteger(
com.android.internal.R.integer.config_shortAnimTime);
mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.decelerate_cubic);
- mThumbnailFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
- com.android.internal.R.interpolator.fast_out_slow_in);
mThumbnailFadeInInterpolator = new Interpolator() {
@Override
public float getInterpolation(float input) {
@@ -276,12 +292,18 @@ public class AppTransition implements Dump {
void prepare() {
if (!isRunning()) {
mAppTransitionState = APP_STATE_IDLE;
+ notifyAppTransitionPendingLocked();
}
}
- void goodToGo() {
+ void goodToGo(AppWindowAnimator openingAppAnimator, AppWindowAnimator closingAppAnimator) {
mNextAppTransition = TRANSIT_UNSET;
mAppTransitionState = APP_STATE_RUNNING;
+ notifyAppTransitionStartingLocked(
+ openingAppAnimator != null ? openingAppAnimator.mAppToken.token : null,
+ closingAppAnimator != null ? closingAppAnimator.mAppToken.token : null,
+ openingAppAnimator != null ? openingAppAnimator.animation : null,
+ closingAppAnimator != null ? closingAppAnimator.animation : null);
}
void clear() {
@@ -294,6 +316,38 @@ public class AppTransition implements Dump {
setAppTransition(AppTransition.TRANSIT_UNSET);
clear();
setReady();
+ notifyAppTransitionCancelledLocked();
+ }
+
+ void registerListenerLocked(AppTransitionListener listener) {
+ mListeners.add(listener);
+ }
+
+ public void notifyAppTransitionFinishedLocked(AppWindowAnimator animator) {
+ IBinder token = animator != null ? animator.mAppToken.token : null;
+ for (int i = 0; i < mListeners.size(); i++) {
+ mListeners.get(i).onAppTransitionFinishedLocked(token);
+ }
+ }
+
+ private void notifyAppTransitionPendingLocked() {
+ for (int i = 0; i < mListeners.size(); i++) {
+ mListeners.get(i).onAppTransitionPendingLocked();
+ }
+ }
+
+ private void notifyAppTransitionCancelledLocked() {
+ for (int i = 0; i < mListeners.size(); i++) {
+ mListeners.get(i).onAppTransitionCancelledLocked();
+ }
+ }
+
+ private void notifyAppTransitionStartingLocked(IBinder openToken,
+ IBinder closeToken, Animation openAnimation, Animation closeAnimation) {
+ for (int i = 0; i < mListeners.size(); i++) {
+ mListeners.get(i).onAppTransitionStartingLocked(openToken, closeToken, openAnimation,
+ closeAnimation);
+ }
}
private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
@@ -447,6 +501,86 @@ public class AppTransition implements Dump {
return a;
}
+ private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame) {
+ final Animation anim;
+ if (enter) {
+ // Reveal will expand and move faster in horizontal direction
+
+ // Start from upper left of start and move to final position
+ final int appWidth = appFrame.width();
+ final int appHeight = appFrame.height();
+
+ // Start from size of launch icon, expand to full width/height
+ Animation clipAnimLR = new ClipRectLRAnimation(
+ (appWidth - mNextAppTransitionStartWidth) / 2,
+ (appWidth + mNextAppTransitionStartWidth) / 2, 0, appWidth);
+ clipAnimLR.setInterpolator(mLinearOutSlowInInterpolator);
+ clipAnimLR.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+ Animation clipAnimTB = new ClipRectTBAnimation(
+ (appHeight - mNextAppTransitionStartHeight) / 2,
+ (appHeight + mNextAppTransitionStartHeight) / 2, 0, appHeight);
+ clipAnimTB.setInterpolator(mFastOutSlowInInterpolator);
+ clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+
+ // Start from middle of launch icon area, move to 0, 0
+ int startMiddleX = mNextAppTransitionStartX +
+ (mNextAppTransitionStartWidth - appWidth) / 2 - appFrame.left;
+ int startMiddleY = mNextAppTransitionStartY +
+ (mNextAppTransitionStartHeight - appHeight) / 2 - appFrame.top;
+
+ TranslateXAnimation translateX = new TranslateXAnimation(
+ Animation.ABSOLUTE, startMiddleX, Animation.ABSOLUTE, 0);
+ translateX.setInterpolator(mLinearOutSlowInInterpolator);
+ translateX.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+ TranslateYAnimation translateY = new TranslateYAnimation(
+ Animation.ABSOLUTE, startMiddleY, Animation.ABSOLUTE, 0);
+ translateY.setInterpolator(mFastOutSlowInInterpolator);
+ translateY.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+
+ // Quick fade-in from icon to app window
+ final int alphaDuration = 100;
+ AlphaAnimation alpha = new AlphaAnimation(0.1f, 1);
+ alpha.setDuration(alphaDuration);
+ alpha.setInterpolator(mLinearInterpolator);
+
+ AnimationSet set = new AnimationSet(false);
+ set.addAnimation(clipAnimLR);
+ set.addAnimation(clipAnimTB);
+ set.addAnimation(translateX);
+ set.addAnimation(translateY);
+ set.addAnimation(alpha);
+ set.initialize(appWidth, appHeight, appWidth, appHeight);
+ anim = set;
+ } else {
+ final long duration;
+ switch (transit) {
+ case TRANSIT_ACTIVITY_OPEN:
+ case TRANSIT_ACTIVITY_CLOSE:
+ duration = mConfigShortAnimTime;
+ break;
+ default:
+ duration = DEFAULT_APP_TRANSITION_DURATION;
+ break;
+ }
+ if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
+ transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
+ // If we are on top of the wallpaper, we need an animation that
+ // correctly handles the wallpaper staying static behind all of
+ // the animated elements. To do this, will just have the existing
+ // element fade out.
+ anim = new AlphaAnimation(1, 0);
+ anim.setDetachWallpaper(true);
+ } else {
+ // For normal animations, the exiting element just holds in place.
+ anim = new AlphaAnimation(1, 1);
+ }
+ anim.setInterpolator(mDecelerateInterpolator);
+ anim.setDuration(duration);
+ anim.setFillAfter(true);
+ }
+ return anim;
+ }
+
/**
* Prepares the specified animation with a standard duration, interpolator, etc.
*/
@@ -522,14 +656,14 @@ public class AppTransition implements Dump {
Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
mNextAppTransitionStartX + (thumbWidth / 2f),
mNextAppTransitionStartY + (thumbHeight / 2f));
- scale.setInterpolator(mThumbnailFastOutSlowInInterpolator);
+ scale.setInterpolator(mFastOutSlowInInterpolator);
scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Animation alpha = new AlphaAnimation(1, 0);
alpha.setInterpolator(mThumbnailFadeOutInterpolator);
alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
Animation translate = new TranslateAnimation(0, 0, 0, -unscaledStartY +
mNextAppTransitionInsets.top);
- translate.setInterpolator(mThumbnailFastOutSlowInInterpolator);
+ translate.setInterpolator(mFastOutSlowInInterpolator);
translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
// This AnimationSet uses the Interpolators assigned above.
@@ -543,14 +677,14 @@ public class AppTransition implements Dump {
Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
mNextAppTransitionStartX + (thumbWidth / 2f),
mNextAppTransitionStartY + (thumbHeight / 2f));
- scale.setInterpolator(mThumbnailFastOutSlowInInterpolator);
+ scale.setInterpolator(mFastOutSlowInInterpolator);
scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Animation alpha = new AlphaAnimation(0f, 1f);
alpha.setInterpolator(mThumbnailFadeInInterpolator);
alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
Animation translate = new TranslateAnimation(0, 0, -unscaledStartY +
mNextAppTransitionInsets.top, 0);
- translate.setInterpolator(mThumbnailFastOutSlowInInterpolator);
+ translate.setInterpolator(mFastOutSlowInInterpolator);
translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
// This AnimationSet uses the Interpolators assigned above.
@@ -562,7 +696,7 @@ public class AppTransition implements Dump {
}
return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, 0,
- mThumbnailFastOutSlowInInterpolator);
+ mFastOutSlowInInterpolator);
}
/**
@@ -698,7 +832,7 @@ public class AppTransition implements Dump {
int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
THUMBNAIL_APP_TRANSITION_DURATION);
return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
- mThumbnailFastOutSlowInInterpolator);
+ mFastOutSlowInInterpolator);
}
/**
@@ -809,7 +943,7 @@ public class AppTransition implements Dump {
Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,
- boolean isFullScreen, boolean isVoiceInteraction) {
+ Rect appFrame, boolean isFullScreen, boolean isVoiceInteraction) {
Animation a;
if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
|| transit == TRANSIT_TASK_OPEN
@@ -845,6 +979,12 @@ public class AppTransition implements Dump {
"applyAnimation:"
+ " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
+ " transit=" + transit + " Callers=" + Debug.getCallers(3));
+ } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
+ a = createClipRevealAnimationLocked(transit, enter, appFrame);
+ if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
+ "applyAnimation:"
+ + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL"
+ + " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
@@ -987,6 +1127,19 @@ public class AppTransition implements Dump {
}
}
+ void overridePendingAppTransitionClipReveal(int startX, int startY,
+ int startWidth, int startHeight) {
+ if (isTransitionSet()) {
+ mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
+ mNextAppTransitionStartX = startX;
+ mNextAppTransitionStartY = startY;
+ mNextAppTransitionStartWidth = startWidth;
+ mNextAppTransitionStartHeight = startHeight;
+ postAnimationCallback();
+ mNextAppTransitionCallback = null;
+ }
+ }
+
void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
IRemoteCallback startedCallback, boolean scaleUp) {
if (isTransitionSet()) {
@@ -1130,32 +1283,34 @@ public class AppTransition implements Dump {
}
@Override
- public void dump(PrintWriter pw) {
- pw.print(" " + this);
- pw.print(" mAppTransitionState="); pw.println(appStateToString());
+ public void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.println(this);
+ pw.print(prefix); pw.print("mAppTransitionState="); pw.println(appStateToString());
if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) {
- pw.print(" mNextAppTransitionType="); pw.println(transitTypeToString());
+ pw.print(prefix); pw.print("mNextAppTransitionType=");
+ pw.println(transitTypeToString());
}
switch (mNextAppTransitionType) {
case NEXT_TRANSIT_TYPE_CUSTOM:
- pw.print(" mNextAppTransitionPackage=");
+ pw.print(prefix); pw.print("mNextAppTransitionPackage=");
pw.println(mNextAppTransitionPackage);
- pw.print(" mNextAppTransitionEnter=0x");
+ pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
pw.print(Integer.toHexString(mNextAppTransitionEnter));
pw.print(" mNextAppTransitionExit=0x");
pw.println(Integer.toHexString(mNextAppTransitionExit));
break;
case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
- pw.print(" mNextAppTransitionPackage=");
+ pw.print(prefix); pw.print("mNextAppTransitionPackage=");
pw.println(mNextAppTransitionPackage);
- pw.print(" mNextAppTransitionInPlace=0x");
+ pw.print(prefix); pw.print("mNextAppTransitionInPlace=0x");
pw.print(Integer.toHexString(mNextAppTransitionInPlace));
break;
case NEXT_TRANSIT_TYPE_SCALE_UP:
- pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
+ pw.print(prefix); pw.print("mNextAppTransitionStartX=");
+ pw.print(mNextAppTransitionStartX);
pw.print(" mNextAppTransitionStartY=");
pw.println(mNextAppTransitionStartY);
- pw.print(" mNextAppTransitionStartWidth=");
+ pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
pw.print(mNextAppTransitionStartWidth);
pw.print(" mNextAppTransitionStartHeight=");
pw.println(mNextAppTransitionStartHeight);
@@ -1164,22 +1319,23 @@ public class AppTransition implements Dump {
case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
- pw.print(" mNextAppTransitionThumbnail=");
+ pw.print(prefix); pw.print("mNextAppTransitionThumbnail=");
pw.print(mNextAppTransitionThumbnail);
pw.print(" mNextAppTransitionStartX=");
pw.print(mNextAppTransitionStartX);
pw.print(" mNextAppTransitionStartY=");
pw.println(mNextAppTransitionStartY);
- pw.print(" mNextAppTransitionStartWidth=");
+ pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
pw.print(mNextAppTransitionStartWidth);
pw.print(" mNextAppTransitionStartHeight=");
pw.println(mNextAppTransitionStartHeight);
- pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
+ pw.print(prefix); pw.print("mNextAppTransitionScaleUp=");
+ pw.println(mNextAppTransitionScaleUp);
break;
}
if (mNextAppTransitionCallback != null) {
- pw.print(" mNextAppTransitionCallback=");
- pw.println(mNextAppTransitionCallback);
+ pw.print(prefix); pw.print("mNextAppTransitionCallback=");
+ pw.println(mNextAppTransitionCallback);
}
}
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 5c81126..55ec9fc 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -17,7 +17,6 @@
package com.android.server.wm;
import android.graphics.Matrix;
-import android.os.RemoteException;
import android.util.Slog;
import android.util.TimeUtils;
import android.view.Display;
@@ -142,6 +141,10 @@ public class AppWindowAnimator {
}
}
+ public boolean isAnimating() {
+ return animation != null || mAppToken.inPendingTransaction;
+ }
+
public void clearThumbnail() {
if (thumbnail != null) {
thumbnail.destroy();
@@ -239,7 +242,7 @@ public class AppWindowAnimator {
}
// This must be called while inside a transaction.
- boolean stepAnimationLocked(long currentTime) {
+ boolean stepAnimationLocked(long currentTime, final int displayId) {
if (mService.okToDisplay()) {
// We will run animations as long as the display isn't frozen.
@@ -289,7 +292,7 @@ public class AppWindowAnimator {
}
mAnimator.setAppLayoutChanges(this, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM,
- "AppWindowToken");
+ "AppWindowToken", displayId);
clearAnimation();
animating = false;
@@ -312,23 +315,7 @@ public class AppWindowAnimator {
for (int i = 0; i < numAllAppWinAnimators; i++) {
mAllAppWinAnimators.get(i).finishExit();
}
- if (mAppToken.mLaunchTaskBehind) {
- try {
- mService.mActivityManager.notifyLaunchTaskBehindComplete(mAppToken.token);
- } catch (RemoteException e) {
- }
- mAppToken.mLaunchTaskBehind = false;
- } else {
- mAppToken.updateReportedVisibilityLocked();
- if (mAppToken.mEnteringAnimation) {
- mAppToken.mEnteringAnimation = false;
- try {
- mService.mActivityManager.notifyEnterAnimationComplete(mAppToken.token);
- } catch (RemoteException e) {
- }
- }
- }
-
+ mService.mAppTransition.notifyAppTransitionFinishedLocked(this);
return false;
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index da25c53..a210223 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -52,11 +52,11 @@ class AppWindowToken extends WindowToken {
final boolean voiceInteraction;
- int groupId = -1;
+ Task mTask;
boolean appFullscreen;
int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean layoutConfigChanges;
- boolean showWhenLocked;
+ boolean showForAllUsers;
// The input dispatching timeout for this application token in nanoseconds.
long inputDispatchingTimeoutNanos;
@@ -107,7 +107,7 @@ class AppWindowToken extends WindowToken {
// Input application handle used by the input dispatcher.
final InputApplicationHandle mInputApplicationHandle;
- boolean mDeferRemoval;
+ boolean mIsExiting;
boolean mLaunchTaskBehind;
boolean mEnteringAnimation;
@@ -252,6 +252,21 @@ class AppWindowToken extends WindowToken {
return false;
}
+ void removeAppFromTaskLocked() {
+ mIsExiting = false;
+ removeAllWindows();
+
+ // Use local variable because removeAppToken will null out mTask.
+ final Task task = mTask;
+ if (task != null) {
+ if (!task.removeAppToken(this)) {
+ Slog.e(WindowManagerService.TAG, "removeAppFromTaskLocked: token=" + this
+ + " not found.");
+ }
+ task.mStack.mExitingAppTokens.remove(this);
+ }
+ }
+
@Override
void removeAllWindows() {
for (int winNdx = allAppWindows.size() - 1; winNdx >= 0;
@@ -266,8 +281,10 @@ class AppWindowToken extends WindowToken {
Slog.w(WindowManagerService.TAG, "removeAllWindows: removing win=" + win);
}
- win.mService.removeWindowLocked(win.mSession, win);
+ service.removeWindowLocked(win);
}
+ allAppWindows.clear();
+ windows.clear();
}
@Override
@@ -279,8 +296,8 @@ class AppWindowToken extends WindowToken {
if (allAppWindows.size() > 0) {
pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
}
- pw.print(prefix); pw.print("groupId="); pw.print(groupId);
- pw.print(" appFullscreen="); pw.print(appFullscreen);
+ pw.print(prefix); pw.print("task="); pw.println(mTask);
+ pw.print(prefix); pw.print(" appFullscreen="); pw.print(appFullscreen);
pw.print(" requestedOrientation="); pw.println(requestedOrientation);
pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
pw.print(" clientHidden="); pw.print(clientHidden);
@@ -304,11 +321,11 @@ class AppWindowToken extends WindowToken {
pw.print(prefix); pw.print("inPendingTransaction=");
pw.println(inPendingTransaction);
}
- if (startingData != null || removed || firstWindowDrawn || mDeferRemoval) {
+ if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
pw.print(prefix); pw.print("startingData="); pw.print(startingData);
pw.print(" removed="); pw.print(removed);
pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
- pw.print(" mDeferRemoval="); pw.println(mDeferRemoval);
+ pw.print(" mIsExiting="); pw.println(mIsExiting);
}
if (startingWindow != null || startingView != null
|| startingDisplayed || startingMoved) {
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 3f5ae56..e385be3 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -168,24 +168,17 @@ public class DimLayer {
mLastBounds.set(mBounds);
}
- /**
- * @param bounds The new bounds to set
- * @param inTransaction Whether the call is made within a surface transaction.
- */
- void setBounds(Rect bounds, boolean inTransaction) {
+ /** @param bounds The new bounds to set */
+ void setBounds(Rect bounds) {
mBounds.set(bounds);
if (isDimming() && !mLastBounds.equals(bounds)) {
try {
- if (!inTransaction) {
- SurfaceControl.openTransaction();
- }
+ SurfaceControl.openTransaction();
adjustBounds();
} catch (RuntimeException e) {
Slog.w(TAG, "Failure setting size", e);
} finally {
- if (!inTransaction) {
- SurfaceControl.closeTransaction();
- }
+ SurfaceControl.closeTransaction();
}
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4f20f50..f914369 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -66,6 +66,7 @@ class DisplayContent {
int mBaseDisplayWidth = 0;
int mBaseDisplayHeight = 0;
int mBaseDisplayDensity = 0;
+ boolean mDisplayScalingDisabled;
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private final Display mDisplay;
@@ -241,23 +242,24 @@ class DisplayContent {
mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
}
}
- mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
+ if (mTapDetector != null) {
+ mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
+ }
}
- void switchUserStacks(int newUserId) {
+ void switchUserStacks() {
final WindowList windows = getWindowList();
for (int i = 0; i < windows.size(); i++) {
final WindowState win = windows.get(i);
if (win.isHiddenFromUserLocked()) {
- if (DEBUG_VISIBILITY) Slog.w(TAG, "user changing " + newUserId + " hiding "
- + win + ", attrs=" + win.mAttrs.type + ", belonging to "
- + win.mOwnerUid);
+ if (DEBUG_VISIBILITY) Slog.w(TAG, "user changing, hiding " + win
+ + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid);
win.hideLw(false);
}
}
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- mStacks.get(stackNdx).switchUser(newUserId);
+ mStacks.get(stackNdx).switchUser();
}
}
@@ -328,16 +330,10 @@ class DisplayContent {
AppTokenList tokens = task.mAppTokens;
for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
AppWindowToken wtoken = tokens.get(tokenNdx);
- if (wtoken.mDeferRemoval) {
- stack.mExitingAppTokens.remove(wtoken);
- wtoken.mDeferRemoval = false;
- mService.removeAppFromTaskLocked(wtoken);
+ if (wtoken.mIsExiting) {
+ wtoken.removeAppFromTaskLocked();
}
}
- if (task.mDeferRemoval) {
- task.mDeferRemoval = false;
- mService.removeTaskLocked(task);
- }
}
}
}
@@ -346,6 +342,12 @@ class DisplayContent {
}
}
+ static int deltaRotation(int oldRotation, int newRotation) {
+ int delta = newRotation - oldRotation;
+ if (delta < 0) delta += 4;
+ return delta;
+ }
+
public void dump(String prefix, PrintWriter pw) {
pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
final String subPrefix = " " + prefix;
@@ -359,6 +361,9 @@ class DisplayContent {
pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
}
+ if (mDisplayScalingDisabled) {
+ pw.println(" noscale");
+ }
pw.print(" cur=");
pw.print(mDisplayInfo.logicalWidth);
pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
@@ -385,7 +390,7 @@ class DisplayContent {
ArrayList<Task> tasks = stack.getTasks();
for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
final Task task = tasks.get(taskNdx);
- pw.print(" mTaskId="); pw.println(task.taskId);
+ pw.print(" mTaskId="); pw.println(task.mTaskId);
AppTokenList tokens = task.mAppTokens;
for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx, ++ndx) {
final AppWindowToken wtoken = tokens.get(tokenNdx);
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index c6951bd..1a125d4 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -24,6 +24,7 @@ import com.android.server.wm.WindowManagerService.H;
import android.content.ClipData;
import android.content.ClipDescription;
import android.graphics.Point;
+import android.graphics.Rect;
import android.graphics.Region;
import android.os.IBinder;
import android.os.Message;
@@ -63,6 +64,7 @@ class DragState {
Display mDisplay;
private final Region mTmpRegion = new Region();
+ private final Rect mTmpRect = new Rect();
DragState(WindowManagerService service, IBinder token, SurfaceControl surface,
int flags, IBinder localWin) {
@@ -411,6 +413,12 @@ class DragState {
continue;
}
+ child.getStackBounds(mTmpRect);
+ if (!mTmpRect.contains(x, y)) {
+ // outside of this window's activity stack == don't tell about drags
+ continue;
+ }
+
child.getTouchableRegion(mTmpRegion);
final int touchFlags = flags &
diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
index 5e4bd8b..4c8a6f9 100644
--- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
+++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
@@ -25,7 +25,6 @@ import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.util.Slog;
import android.view.Display;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
diff --git a/services/core/java/com/android/server/wm/FocusedStackFrame.java b/services/core/java/com/android/server/wm/FocusedStackFrame.java
index f1f5fe8..826fe97 100644
--- a/services/core/java/com/android/server/wm/FocusedStackFrame.java
+++ b/services/core/java/com/android/server/wm/FocusedStackFrame.java
@@ -16,14 +16,14 @@
package com.android.server.wm;
-import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.graphics.Region;
import android.util.Slog;
import android.view.Display;
import android.view.Surface.OutOfResourcesException;
@@ -35,14 +35,17 @@ import com.android.server.wm.WindowStateAnimator.SurfaceTrace;
class FocusedStackFrame {
private static final String TAG = "FocusedStackFrame";
- private static final int THICKNESS = 10;
+ private static final boolean DEBUG = false;
+ private static final int THICKNESS = 2;
private static final float ALPHA = 0.3f;
private final SurfaceControl mSurfaceControl;
private final Surface mSurface = new Surface();
+ private final Paint mInnerPaint = new Paint();
+ private final Paint mOuterPaint = new Paint();
+ private final Rect mBounds = new Rect();
private final Rect mLastBounds = new Rect();
- final Rect mBounds = new Rect();
- private final Rect mTmpDrawRect = new Rect();
+ private int mLayer = -1;
public FocusedStackFrame(Display display, SurfaceSession session) {
SurfaceControl ctrl = null;
@@ -60,83 +63,84 @@ class FocusedStackFrame {
} catch (OutOfResourcesException e) {
}
mSurfaceControl = ctrl;
+
+ mInnerPaint.setStyle(Paint.Style.STROKE);
+ mInnerPaint.setStrokeWidth(THICKNESS);
+ mInnerPaint.setColor(Color.WHITE);
+ mOuterPaint.setStyle(Paint.Style.STROKE);
+ mOuterPaint.setStrokeWidth(THICKNESS);
+ mOuterPaint.setColor(Color.BLACK);
}
- private void draw(Rect bounds, int color) {
- if (false && DEBUG_STACK) Slog.i(TAG, "draw: bounds=" + bounds.toShortString() +
- " color=" + Integer.toHexString(color));
- mTmpDrawRect.set(bounds);
+ private void draw() {
+ if (mLastBounds.isEmpty()) {
+ // Currently unset. Set it.
+ mLastBounds.set(mBounds);
+ }
+
+ if (DEBUG) Slog.i(TAG, "draw: mBounds=" + mBounds + " mLastBounds=" + mLastBounds);
+
Canvas c = null;
try {
- c = mSurface.lockCanvas(mTmpDrawRect);
+ c = mSurface.lockCanvas(mLastBounds);
} catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Unable to lock canvas", e);
} catch (Surface.OutOfResourcesException e) {
+ Slog.e(TAG, "Unable to lock canvas", e);
}
if (c == null) {
+ if (DEBUG) Slog.w(TAG, "Canvas is null...");
return;
}
- final int w = bounds.width();
- final int h = bounds.height();
-
- // Top
- mTmpDrawRect.set(0, 0, w, THICKNESS);
- c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
- c.drawColor(color);
- // Left (not including Top or Bottom stripe).
- mTmpDrawRect.set(0, THICKNESS, THICKNESS, h - THICKNESS);
- c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
- c.drawColor(color);
- // Right (not including Top or Bottom stripe).
- mTmpDrawRect.set(w - THICKNESS, THICKNESS, w, h - THICKNESS);
- c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
- c.drawColor(color);
- // Bottom
- mTmpDrawRect.set(0, h - THICKNESS, w, h);
- c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
- c.drawColor(color);
-
+ c.drawRect(0, 0, mBounds.width(), mBounds.height(), mOuterPaint);
+ c.drawRect(THICKNESS, THICKNESS, mBounds.width() - THICKNESS, mBounds.height() - THICKNESS,
+ mInnerPaint);
+ if (DEBUG) Slog.w(TAG, "c.width=" + c.getWidth() + " c.height=" + c.getHeight()
+ + " c.clip=" + c .getClipBounds());
mSurface.unlockCanvasAndPost(c);
+ mLastBounds.set(mBounds);
}
- private void positionSurface(Rect bounds) {
- if (false && DEBUG_STACK) Slog.i(TAG, "positionSurface: bounds=" + bounds.toShortString());
- mSurfaceControl.setSize(bounds.width(), bounds.height());
- mSurfaceControl.setPosition(bounds.left, bounds.top);
- }
-
- // Note: caller responsible for being inside
- // Surface.openTransaction() / closeTransaction()
- public void setVisibility(boolean on) {
- if (false && DEBUG_STACK) Slog.i(TAG, "setVisibility: on=" + on +
- " mLastBounds=" + mLastBounds.toShortString() +
- " mBounds=" + mBounds.toShortString());
+ private void setupSurface(boolean visible) {
if (mSurfaceControl == null) {
return;
}
- if (on) {
- if (!mLastBounds.equals(mBounds)) {
- // Erase the previous rectangle.
- positionSurface(mLastBounds);
- draw(mLastBounds, Color.TRANSPARENT);
- // Draw the latest rectangle.
- positionSurface(mBounds);
- draw(mBounds, Color.WHITE);
- // Update the history.
- mLastBounds.set(mBounds);
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setupSurface");
+ SurfaceControl.openTransaction();
+ try {
+ if (visible) {
+ mSurfaceControl.setPosition(mBounds.left, mBounds.top);
+ mSurfaceControl.setSize(mBounds.width(), mBounds.height());
+ mSurfaceControl.show();
+ } else {
+ mSurfaceControl.hide();
}
- mSurfaceControl.show();
- } else {
- mSurfaceControl.hide();
+ } finally {
+ SurfaceControl.closeTransaction();
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setupSurface");
}
}
- public void setBounds(TaskStack stack) {
- stack.getBounds(mBounds);
- if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + mBounds);
+ void setVisibility(TaskStack stack) {
+ if (stack == null || stack.isFullscreen()) {
+ setupSurface(false);
+ } else {
+ stack.getBounds(mBounds);
+ setupSurface(true);
+ if (!mBounds.equals(mLastBounds)) {
+ draw();
+ }
+ }
}
- public void setLayer(int layer) {
- mSurfaceControl.setLayer(layer);
+ // Note: caller responsible for being inside
+ // Surface.openTransaction() / closeTransaction()
+ void setLayer(int layer) {
+ if (mLayer == layer) {
+ return;
+ }
+ mLayer = layer;
+ mSurfaceControl.setLayer(mLayer);
}
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index ad50e05a..c24fcb3 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -78,7 +78,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
WindowState windowState = (WindowState) inputWindowHandle.windowState;
if (windowState != null) {
Slog.i(WindowManagerService.TAG, "WINDOW DIED " + windowState);
- mService.removeWindowLocked(windowState.mSession, windowState);
+ mService.removeWindowLocked(windowState);
}
}
}
@@ -239,9 +239,6 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
// As an optimization, we could try to prune the list of windows but this turns
// out to be difficult because only the native code knows for sure which window
// currently has touch focus.
- final WindowStateAnimator universeBackground = mService.mAnimator.mUniverseBackground;
- final int aboveUniverseLayer = mService.mAnimator.mAboveUniverseLayer;
- boolean addedUniverse = false;
boolean disableWallpaperTouchEvents = false;
// If there's a drag in flight, provide a pseudowindow to catch drag input
@@ -299,20 +296,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
mService.mDragState.sendDragStartedIfNeededLw(child);
}
- if (universeBackground != null && !addedUniverse
- && child.mBaseLayer < aboveUniverseLayer && onDefaultDisplay) {
- final WindowState u = universeBackground.mWin;
- if (u.mInputChannel != null && u.mInputWindowHandle != null) {
- addInputWindowHandleLw(u.mInputWindowHandle, u, u.mAttrs.flags,
- u.mAttrs.type, true, u == mInputFocus, false);
- }
- addedUniverse = true;
- }
-
- if (child.mWinAnimator != universeBackground) {
- addInputWindowHandleLw(inputWindowHandle, child, flags, type, isVisible,
- hasFocus, hasWallpaper);
- }
+ addInputWindowHandleLw(inputWindowHandle, child, flags, type, isVisible, hasFocus,
+ hasWallpaper);
}
}
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index f79896b..7dd716e 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -291,12 +291,6 @@ class ScreenRotationAnimation {
return mSurfaceControl != null;
}
- static int deltaRotation(int oldRotation, int newRotation) {
- int delta = newRotation - oldRotation;
- if (delta < 0) delta += 4;
- return delta;
- }
-
private void setSnapshotTransformInTransaction(Matrix matrix, float alpha) {
if (mSurfaceControl != null) {
matrix.getValues(mTmpFloats);
@@ -352,7 +346,7 @@ class ScreenRotationAnimation {
// Compute the transformation matrix that must be applied
// to the snapshot to make it stay in the same original position
// with the current screen rotation.
- int delta = deltaRotation(rotation, Surface.ROTATION_0);
+ int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0);
createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
@@ -391,7 +385,7 @@ class ScreenRotationAnimation {
boolean firstStart = false;
// Figure out how the screen has moved from the original rotation.
- int delta = deltaRotation(mCurRotation, mOriginalRotation);
+ int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
&& (!dismissing || delta != Surface.ROTATION_0)) {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index a1d145c..487483e 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -446,20 +446,6 @@ final class Session extends IWindowSession.Stub
mService.wallpaperCommandComplete(window, result);
}
- public void setUniverseTransform(IBinder window, float alpha, float offx, float offy,
- float dsdx, float dtdx, float dsdy, float dtdy) {
- synchronized(mService.mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- mService.setUniverseTransformLocked(
- mService.windowForClientLocked(this, window, true),
- alpha, offx, offy, dsdx, dtdx, dsdy, dtdy);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
synchronized(mService.mWindowMap) {
final long identity = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b49b87c..0c3cf65 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -17,22 +17,25 @@
package com.android.server.wm;
import static com.android.server.wm.WindowManagerService.TAG;
+import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
import android.util.EventLog;
import android.util.Slog;
+import com.android.server.EventLogTags;
class Task {
TaskStack mStack;
final AppTokenList mAppTokens = new AppTokenList();
- final int taskId;
+ final int mTaskId;
final int mUserId;
boolean mDeferRemoval = false;
+ final WindowManagerService mService;
- Task(AppWindowToken wtoken, TaskStack stack, int userId) {
- taskId = wtoken.groupId;
- mAppTokens.add(wtoken);
+ Task(int taskId, TaskStack stack, int userId, WindowManagerService service) {
+ mTaskId = taskId;
mStack = stack;
mUserId = userId;
+ mService = service;
}
DisplayContent getDisplayContent() {
@@ -41,22 +44,60 @@ class Task {
void addAppToken(int addPos, AppWindowToken wtoken) {
final int lastPos = mAppTokens.size();
- for (int pos = 0; pos < lastPos && pos < addPos; ++pos) {
- if (mAppTokens.get(pos).removed) {
- // addPos assumes removed tokens are actually gone.
- ++addPos;
+ if (addPos >= lastPos) {
+ addPos = lastPos;
+ } else {
+ for (int pos = 0; pos < lastPos && pos < addPos; ++pos) {
+ if (mAppTokens.get(pos).removed) {
+ // addPos assumes removed tokens are actually gone.
+ ++addPos;
+ }
}
}
mAppTokens.add(addPos, wtoken);
+ wtoken.mTask = this;
mDeferRemoval = false;
}
+ void removeLocked() {
+ if (!mAppTokens.isEmpty() && mStack.isAnimating()) {
+ if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + mTaskId);
+ mDeferRemoval = true;
+ return;
+ }
+ if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + mTaskId);
+ EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "removeTask");
+ mDeferRemoval = false;
+ mStack.removeTask(this);
+ mService.mTaskIdToTask.delete(mTaskId);
+ }
+
+ void moveTaskToStack(TaskStack stack, boolean toTop) {
+ if (stack == mStack) {
+ return;
+ }
+ if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: removing taskId=" + mTaskId
+ + " from stack=" + mStack);
+ EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "moveTask");
+ if (mStack != null) {
+ mStack.removeTask(this);
+ }
+ stack.addTask(this, toTop);
+ }
+
boolean removeAppToken(AppWindowToken wtoken) {
boolean removed = mAppTokens.remove(wtoken);
if (mAppTokens.size() == 0) {
- EventLog.writeEvent(com.android.server.EventLogTags.WM_TASK_REMOVED, taskId,
+ EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId,
"removeAppToken: last token");
+ if (mDeferRemoval) {
+ removeLocked();
+ }
}
+ wtoken.mTask = null;
+ /* Leave mTaskId for now, it might be useful for debug
+ wtoken.mTaskId = -1;
+ */
return removed;
}
@@ -66,8 +107,13 @@ class Task {
}
}
+ boolean showForAllUsers() {
+ final int tokensCount = mAppTokens.size();
+ return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;
+ }
+
@Override
public String toString() {
- return "{taskId=" + taskId + " appTokens=" + mAppTokens + " mdr=" + mDeferRemoval + "}";
+ return "{taskId=" + mTaskId + " appTokens=" + mAppTokens + " mdr=" + mDeferRemoval + "}";
}
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index d313e3f..7cdf8b2 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -19,11 +19,15 @@ package com.android.server.wm;
import static com.android.server.wm.WindowManagerService.DEBUG_TASK_MOVEMENT;
import static com.android.server.wm.WindowManagerService.TAG;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Debug;
+import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Slog;
import android.util.TypedValue;
+import android.view.Surface;
+
import com.android.server.EventLogTags;
import java.io.PrintWriter;
@@ -49,6 +53,8 @@ public class TaskStack {
/** For comparison with DisplayContent bounds. */
private Rect mTmpRect = new Rect();
+ /** For handling display rotations. */
+ private Rect mTmpRect2 = new Rect();
/** Content limits relative to the DisplayContent this sits in. */
private Rect mBounds = new Rect();
@@ -78,9 +84,24 @@ public class TaskStack {
/** Detach this stack from its display when animation completes. */
boolean mDeferDetach;
+ // Contains configurations settings that are different from the global configuration due to
+ // stack specific operations. E.g. {@link #setBounds}.
+ Configuration mOverrideConfig;
+ // True if the stack was forced to fullscreen disregarding the override configuration.
+ private boolean mForceFullscreen;
+ // The {@link #mBounds} before the stack was forced to fullscreen. Will be restored as the
+ // stack bounds once the stack is no longer forced to fullscreen.
+ final private Rect mPreForceFullscreenBounds;
+
+ // Device rotation as of the last time {@link #mBounds} was set.
+ int mRotation;
+
TaskStack(WindowManagerService service, int stackId) {
mService = service;
mStackId = stackId;
+ mOverrideConfig = Configuration.EMPTY;
+ mForceFullscreen = false;
+ mPreForceFullscreenBounds = new Rect();
// TODO: remove bounds from log, they are always 0.
EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top,
mBounds.right, mBounds.bottom);
@@ -95,8 +116,6 @@ public class TaskStack {
}
void resizeWindows() {
- final boolean underStatusBar = mBounds.top == 0;
-
final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
@@ -109,27 +128,40 @@ public class TaskStack {
"setBounds: Resizing " + win);
resizingWindows.add(win);
}
- win.mUnderStatusBar = underStatusBar;
}
}
}
}
+ /** Set the stack bounds. Passing in null sets the bounds to fullscreen. */
boolean setBounds(Rect bounds) {
boolean oldFullscreen = mFullscreen;
+ int rotation = Surface.ROTATION_0;
if (mDisplayContent != null) {
mDisplayContent.getLogicalDisplayRect(mTmpRect);
- mFullscreen = mTmpRect.equals(bounds);
+ rotation = mDisplayContent.getDisplayInfo().rotation;
+ if (bounds == null) {
+ bounds = mTmpRect;
+ mFullscreen = true;
+ } else {
+ bounds.intersect(mTmpRect); // ensure bounds are entirely within the display rect
+ mFullscreen = mTmpRect.equals(bounds);
+ }
}
- if (mBounds.equals(bounds) && oldFullscreen == mFullscreen) {
+ if (bounds == null) {
+ // Can't set to fullscreen if we don't have a display to get bounds from...
+ return false;
+ }
+ if (mBounds.equals(bounds) && oldFullscreen == mFullscreen && mRotation == rotation) {
return false;
}
- mDimLayer.setBounds(bounds, false);
- mAnimationBackgroundSurface.setBounds(bounds, false);
+ mDimLayer.setBounds(bounds);
+ mAnimationBackgroundSurface.setBounds(bounds);
mBounds.set(bounds);
-
+ mRotation = rotation;
+ updateOverrideConfiguration();
return true;
}
@@ -137,10 +169,67 @@ public class TaskStack {
out.set(mBounds);
}
+ private void updateOverrideConfiguration() {
+ final Configuration serviceConfig = mService.mCurConfiguration;
+ if (mFullscreen) {
+ mOverrideConfig = Configuration.EMPTY;
+ return;
+ }
+
+ if (mOverrideConfig == Configuration.EMPTY) {
+ mOverrideConfig = new Configuration();
+ }
+
+ // TODO(multidisplay): Update Dp to that of display stack is on.
+ final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+ mOverrideConfig.screenWidthDp =
+ Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
+ mOverrideConfig.screenHeightDp =
+ Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
+ mOverrideConfig.smallestScreenWidthDp =
+ Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
+ mOverrideConfig.orientation =
+ (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
+ ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
+ }
+
void updateDisplayInfo() {
- if (mFullscreen && mDisplayContent != null) {
+ if (mFullscreen) {
+ setBounds(null);
+ } else if (mDisplayContent != null) {
+ final int newRotation = mDisplayContent.getDisplayInfo().rotation;
+ if (mRotation == newRotation) {
+ return;
+ }
+
+ // Device rotation changed. We don't want the stack to move around on the screen when
+ // this happens, so update the stack bounds so it stays in the same place.
+ final int rotationDelta = DisplayContent.deltaRotation(mRotation, newRotation);
mDisplayContent.getLogicalDisplayRect(mTmpRect);
- setBounds(mTmpRect);
+ switch (rotationDelta) {
+ case Surface.ROTATION_0:
+ mTmpRect2.set(mBounds);
+ break;
+ case Surface.ROTATION_90:
+ mTmpRect2.top = mTmpRect.bottom - mBounds.right;
+ mTmpRect2.left = mBounds.top;
+ mTmpRect2.right = mTmpRect2.left + mBounds.height();
+ mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
+ break;
+ case Surface.ROTATION_180:
+ mTmpRect2.top = mTmpRect.bottom - mBounds.bottom;
+ mTmpRect2.left = mTmpRect.right - mBounds.right;
+ mTmpRect2.right = mTmpRect2.left + mBounds.width();
+ mTmpRect2.bottom = mTmpRect2.top + mBounds.height();
+ break;
+ case Surface.ROTATION_270:
+ mTmpRect2.top = mBounds.left;
+ mTmpRect2.left = mTmpRect.right - mBounds.bottom;
+ mTmpRect2.right = mTmpRect2.left + mBounds.height();
+ mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
+ break;
+ }
+ setBounds(mTmpRect2);
}
}
@@ -148,6 +237,28 @@ public class TaskStack {
return mFullscreen;
}
+ /** Forces the stack to fullscreen if input is true, else un-forces the stack from fullscreen.
+ * Returns true if something happened.
+ */
+ boolean forceFullscreen(boolean forceFullscreen) {
+ if (mForceFullscreen == forceFullscreen) {
+ return false;
+ }
+ mForceFullscreen = forceFullscreen;
+ if (forceFullscreen) {
+ if (mFullscreen) {
+ return false;
+ }
+ mPreForceFullscreenBounds.set(mBounds);
+ return setBounds(null);
+ } else {
+ if (!mFullscreen || mPreForceFullscreenBounds.isEmpty()) {
+ return false;
+ }
+ return setBounds(mPreForceFullscreenBounds);
+ }
+ }
+
boolean isAnimating() {
for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
@@ -164,21 +275,28 @@ public class TaskStack {
return false;
}
+ void addTask(Task task, boolean toTop) {
+ addTask(task, toTop, task.showForAllUsers());
+ }
+
/**
* Put a Task in this stack. Used for adding and moving.
* @param task The task to add.
* @param toTop Whether to add it to the top or bottom.
+ * @param showForAllUsers Whether to show the task regardless of the current user.
*/
- void addTask(Task task, boolean toTop) {
+ void addTask(Task task, boolean toTop, boolean showForAllUsers) {
int stackNdx;
if (!toTop) {
stackNdx = 0;
} else {
stackNdx = mTasks.size();
- if (!mService.isCurrentProfileLocked(task.mUserId)) {
+ if (!showForAllUsers && !mService.isCurrentProfileLocked(task.mUserId)) {
// Place the task below all current user tasks.
while (--stackNdx >= 0) {
- if (!mService.isCurrentProfileLocked(mTasks.get(stackNdx).mUserId)) {
+ final Task tmpTask = mTasks.get(stackNdx);
+ if (!tmpTask.showForAllUsers()
+ || !mService.isCurrentProfileLocked(tmpTask.mUserId)) {
break;
}
}
@@ -194,7 +312,7 @@ public class TaskStack {
if (toTop) {
mDisplayContent.moveStack(this, true);
}
- EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.taskId, toTop ? 1 : 0, stackNdx);
+ EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.mTaskId, toTop ? 1 : 0, stackNdx);
}
void moveTaskToTop(Task task) {
@@ -224,6 +342,13 @@ public class TaskStack {
}
mDisplayContent.layoutNeeded = true;
}
+ for (int appNdx = mExitingAppTokens.size() - 1; appNdx >= 0; --appNdx) {
+ final AppWindowToken wtoken = mExitingAppTokens.get(appNdx);
+ if (wtoken.mTask == task) {
+ wtoken.mIsExiting = false;
+ mExitingAppTokens.remove(appNdx);
+ }
+ }
}
void attachDisplayContent(DisplayContent displayContent) {
@@ -246,7 +371,7 @@ public class TaskStack {
for (int appNdx = appWindowTokens.size() - 1; appNdx >= 0; --appNdx) {
final WindowList appWindows = appWindowTokens.get(appNdx).allAppWindows;
for (int winNdx = appWindows.size() - 1; winNdx >= 0; --winNdx) {
- mService.removeWindowInnerLocked(null, appWindows.get(winNdx));
+ mService.removeWindowInnerLocked(appWindows.get(winNdx));
doAnotherLayoutPass = true;
}
}
@@ -255,10 +380,8 @@ public class TaskStack {
mService.requestTraversalLocked();
}
- mAnimationBackgroundSurface.destroySurface();
- mAnimationBackgroundSurface = null;
- mDimLayer.destroySurface();
- mDimLayer = null;
+ close();
+
mDisplayContent = null;
}
@@ -338,18 +461,24 @@ public class TaskStack {
void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
// Only set dim params on the highest dimmed layer.
- final WindowStateAnimator existingDimWinAnimator = mDimWinAnimator;
// Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
- if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
- || !existingDimWinAnimator.mSurfaceShown
- || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
+ if (newWinAnimator.mSurfaceShown && (mDimWinAnimator == null
+ || !mDimWinAnimator.mSurfaceShown
+ || mDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
mDimWinAnimator = newWinAnimator;
+ if (mDimWinAnimator.mWin.mAppToken == null
+ && !mFullscreen && mDisplayContent != null) {
+ // Dim should cover the entire screen for system windows.
+ mDisplayContent.getLogicalDisplayRect(mTmpRect);
+ mDimLayer.setBounds(mTmpRect);
+ }
}
}
void stopDimmingIfNeeded() {
if (!mDimmingTag && isDimming()) {
mDimWinAnimator = null;
+ mDimLayer.setBounds(mBounds);
}
}
@@ -364,11 +493,11 @@ public class TaskStack {
}
}
- void switchUser(int userId) {
+ void switchUser() {
int top = mTasks.size();
for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
Task task = mTasks.get(taskNdx);
- if (mService.isCurrentProfileLocked(task.mUserId)) {
+ if (mService.isCurrentProfileLocked(task.mUserId) || task.showForAllUsers()) {
mTasks.remove(taskNdx);
mTasks.add(task);
--top;
@@ -377,8 +506,14 @@ public class TaskStack {
}
void close() {
- mDimLayer.mDimSurface.destroy();
- mAnimationBackgroundSurface.mDimSurface.destroy();
+ if (mAnimationBackgroundSurface != null) {
+ mAnimationBackgroundSurface.destroySurface();
+ mAnimationBackgroundSurface = null;
+ }
+ if (mDimLayer != null) {
+ mDimLayer.destroySurface();
+ mDimLayer = null;
+ }
}
public void dump(String prefix, PrintWriter pw) {
@@ -393,7 +528,7 @@ public class TaskStack {
}
if (mDimLayer.isDimming()) {
pw.print(prefix); pw.println("mDimLayer:");
- mDimLayer.printTo(prefix, pw);
+ mDimLayer.printTo(prefix + " ", pw);
pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
}
if (!mExitingAppTokens.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java
index e226e3d..ba3ce36 100644
--- a/services/core/java/com/android/server/wm/Watermark.java
+++ b/services/core/java/com/android/server/wm/Watermark.java
@@ -84,7 +84,7 @@ class Watermark {
int fontSize = WindowManagerService.getPropertyInt(tokens, 1,
TypedValue.COMPLEX_UNIT_DIP, 20, dm);
- mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint = new Paint();
mTextPaint.setTextSize(fontSize);
mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index e833511..52071cc 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -30,8 +30,6 @@ import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENT
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING;
import android.content.Context;
-import android.os.Debug;
-import android.os.SystemClock;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -41,6 +39,7 @@ import android.view.SurfaceControl;
import android.view.WindowManagerPolicy;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
+import android.view.Choreographer;
import com.android.server.wm.WindowManagerService.LayoutFields;
@@ -61,9 +60,13 @@ public class WindowAnimator {
final Context mContext;
final WindowManagerPolicy mPolicy;
+ /** Is any window animating? */
boolean mAnimating;
- final Runnable mAnimationRunnable;
+ /** Is any app window animating? */
+ boolean mAppWindowAnimating;
+
+ final Choreographer.FrameCallback mAnimationFrameCallback;
/** Time of current animation step. Reset on each iteration */
long mCurrentTime;
@@ -78,9 +81,6 @@ public class WindowAnimator {
* seen. If multiple windows satisfy this, use the lowest window. */
WindowState mWindowDetachedWallpaper = null;
- WindowStateAnimator mUniverseBackground = null;
- int mAboveUniverseLayer = 0;
-
int mBulkUpdateParams = 0;
Object mLastWindowFreezeSource;
@@ -118,12 +118,11 @@ public class WindowAnimator {
mContext = service.mContext;
mPolicy = service.mPolicy;
- mAnimationRunnable = new Runnable() {
- @Override
- public void run() {
+ mAnimationFrameCallback = new Choreographer.FrameCallback() {
+ public void doFrame(long frameTimeNs) {
synchronized (mService.mWindowMap) {
mService.mAnimationScheduled = false;
- animateLocked();
+ animateLocked(frameTimeNs);
}
}
};
@@ -149,35 +148,6 @@ public class WindowAnimator {
mDisplayContentsAnimators.delete(displayId);
}
- void hideWallpapersLocked(final WindowState w) {
- final WindowState wallpaperTarget = mService.mWallpaperTarget;
- final WindowState lowerWallpaperTarget = mService.mLowerWallpaperTarget;
- final ArrayList<WindowToken> wallpaperTokens = mService.mWallpaperTokens;
-
- if ((wallpaperTarget == w && lowerWallpaperTarget == null) || wallpaperTarget == null) {
- final int numTokens = wallpaperTokens.size();
- for (int i = numTokens - 1; i >= 0; i--) {
- final WindowToken token = wallpaperTokens.get(i);
- final int numWindows = token.windows.size();
- for (int j = numWindows - 1; j >= 0; j--) {
- final WindowState wallpaper = token.windows.get(j);
- final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
- if (!winAnimator.mLastHidden) {
- winAnimator.hide();
- mService.dispatchWallpaperVisibility(wallpaper, false);
- setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
- WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
- }
- }
- if (WindowManagerService.DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG,
- "Hiding wallpaper " + token + " from " + w
- + " target=" + wallpaperTarget + " lower=" + lowerWallpaperTarget
- + "\n" + Debug.getCallers(5, " "));
- token.hidden = true;
- }
- }
- }
-
private void updateAppWindowsLocked(int displayId) {
ArrayList<TaskStack> stacks = mService.getDisplayContentLocked(displayId).getStacks();
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
@@ -189,13 +159,13 @@ public class WindowAnimator {
final AppWindowAnimator appAnimator = tokens.get(tokenNdx).mAppAnimator;
final boolean wasAnimating = appAnimator.animation != null
&& appAnimator.animation != AppWindowAnimator.sDummyAnimation;
- if (appAnimator.stepAnimationLocked(mCurrentTime)) {
- mAnimating = true;
+ if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) {
+ mAnimating = mAppWindowAnimating = true;
} else if (wasAnimating) {
// stopped animating, do one more pass through the layout
setAppLayoutChanges(appAnimator,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
- "appToken " + appAnimator.mAppToken + " done");
+ "appToken " + appAnimator.mAppToken + " done", displayId);
if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
"updateWindowsApps...: done animating " + appAnimator.mAppToken);
}
@@ -208,12 +178,12 @@ public class WindowAnimator {
final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator;
final boolean wasAnimating = appAnimator.animation != null
&& appAnimator.animation != AppWindowAnimator.sDummyAnimation;
- if (appAnimator.stepAnimationLocked(mCurrentTime)) {
- mAnimating = true;
+ if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) {
+ mAnimating = mAppWindowAnimating = true;
} else if (wasAnimating) {
// stopped animating, do one more pass through the layout
setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
- "exiting appToken " + appAnimator.mAppToken + " done");
+ "exiting appToken " + appAnimator.mAppToken + " done", displayId);
if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
"updateWindowsApps...: done animating exiting " + appAnimator.mAppToken);
}
@@ -231,9 +201,11 @@ public class WindowAnimator {
null : winShowWhenLocked.mAppToken;
final boolean hideWhenLocked =
!(((win.mIsImWindow || imeTarget == win) && showImeOverKeyguard)
- || (appShowWhenLocked != null && (appShowWhenLocked == win.mAppToken ||
+ || (appShowWhenLocked != null && (appShowWhenLocked == win.mAppToken
+ // Show all SHOW_WHEN_LOCKED windows while they're animating
+ || (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 && win.isAnimatingLw()
// Show error dialogs over apps that dismiss keyguard.
- (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
+ || (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
return ((mForceHiding == KEYGUARD_ANIMATING_IN)
&& (!win.mWinAnimator.isAnimating() || hideWhenLocked))
|| ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked);
@@ -605,11 +577,11 @@ public class WindowAnimator {
// This will set mOrientationChangeComplete and cause a pass through layout.
setAppLayoutChanges(appAnimator,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
- "testTokenMayBeDrawnLocked: freezingScreen");
+ "testTokenMayBeDrawnLocked: freezingScreen", displayId);
} else {
setAppLayoutChanges(appAnimator,
WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM,
- "testTokenMayBeDrawnLocked");
+ "testTokenMayBeDrawnLocked", displayId);
// We can now show all of the drawn windows!
if (!mService.mOpeningApps.contains(wtoken)) {
@@ -624,15 +596,16 @@ public class WindowAnimator {
/** Locked on mService.mWindowMap. */
- private void animateLocked() {
+ private void animateLocked(long frameTimeNs) {
if (!mInitialized) {
return;
}
- mCurrentTime = SystemClock.uptimeMillis();
+ mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
boolean wasAnimating = mAnimating;
mAnimating = false;
+ mAppWindowAnimating = false;
if (WindowManagerService.DEBUG_WINDOW_TRACE) {
Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
}
@@ -794,6 +767,7 @@ public class WindowAnimator {
} else if (dumpAll) {
pw.print(subPrefix); pw.println("no ScreenRotationAnimation ");
}
+ pw.println();
}
pw.println();
@@ -814,42 +788,36 @@ public class WindowAnimator {
pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
pw.println(mWindowDetachedWallpaper);
}
- if (mUniverseBackground != null) {
- pw.print(prefix); pw.print("mUniverseBackground="); pw.print(mUniverseBackground);
- pw.print(" mAboveUniverseLayer="); pw.println(mAboveUniverseLayer);
- }
}
int getPendingLayoutChanges(final int displayId) {
if (displayId < 0) {
return 0;
}
- DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
return (displayContent != null) ? displayContent.pendingLayoutChanges : 0;
}
void setPendingLayoutChanges(final int displayId, final int changes) {
- if (displayId >= 0) {
- DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
- if (displayContent != null) {
- displayContent.pendingLayoutChanges |= changes;
- }
+ if (displayId < 0) {
+ return;
+ }
+ final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
+ if (displayContent != null) {
+ displayContent.pendingLayoutChanges |= changes;
}
}
- void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) {
- // Used to track which displays layout changes have been done.
- SparseIntArray displays = new SparseIntArray(2);
+ void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String reason,
+ final int displayId) {
WindowList windows = appAnimator.mAppToken.allAppWindows;
for (int i = windows.size() - 1; i >= 0; i--) {
- final int displayId = windows.get(i).getDisplayId();
- if (displayId >= 0 && displays.indexOfKey(displayId) < 0) {
+ if (displayId == windows.get(i).getDisplayId()) {
setPendingLayoutChanges(displayId, changes);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
- mService.debugLayoutRepeats(s, getPendingLayoutChanges(displayId));
+ mService.debugLayoutRepeats(reason, getPendingLayoutChanges(displayId));
}
- // Keep from processing this display again.
- displays.put(displayId, changes);
+ break;
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e9df96b..6bf68e8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
import static android.view.WindowManager.LayoutParams.*;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -28,9 +29,8 @@ import android.view.IWindowId;
import android.view.IWindowSessionCallback;
import android.view.WindowContentFrameStats;
+import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.app.IBatteryStats;
-import com.android.internal.policy.PolicyManager;
-import com.android.internal.policy.impl.PhoneWindowManager;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -39,12 +39,14 @@ import com.android.internal.view.WindowManagerPolicyThread;
import com.android.server.AttributeCache;
import com.android.server.DisplayThread;
import com.android.server.EventLogTags;
+import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
import com.android.server.input.InputManagerService;
import com.android.server.power.ShutdownThread;
+import com.android.server.policy.PhoneWindowManager;
import android.Manifest;
import android.app.ActivityManagerNative;
@@ -65,11 +67,9 @@ import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
-import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
@@ -128,7 +128,6 @@ import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
-import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy;
@@ -137,7 +136,6 @@ import android.view.WindowManagerPolicy.FakeWindow;
import android.view.WindowManagerPolicy.PointerEventListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
-import android.view.animation.Transformation;
import java.io.BufferedWriter;
import java.io.DataInputStream;
@@ -153,6 +151,7 @@ import java.io.StringWriter;
import java.net.Socket;
import java.text.DateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
@@ -181,7 +180,6 @@ public class WindowManagerService extends IWindowManager.Stub
static final boolean DEBUG_CONFIGURATION = false;
static final boolean DEBUG_APP_TRANSITIONS = false;
static final boolean DEBUG_STARTING_WINDOW = false;
- static final boolean DEBUG_REORDER = false;
static final boolean DEBUG_WALLPAPER = false;
static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
static final boolean DEBUG_DRAG = false;
@@ -284,12 +282,6 @@ public class WindowManagerService extends IWindowManager.Stub
// The name of the boot animation service in init.rc.
private static final String BOOT_ANIMATION_SERVICE = "bootanim";
- /** Minimum value for attachStack and resizeStack weight value */
- public static final float STACK_WEIGHT_MIN = 0.2f;
-
- /** Maximum value for attachStack and resizeStack weight value */
- public static final float STACK_WEIGHT_MAX = 0.8f;
-
static final int UPDATE_FOCUS_NORMAL = 0;
static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
@@ -346,7 +338,7 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean mLimitedAlphaCompositing;
- final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
+ final WindowManagerPolicy mPolicy = new PhoneWindowManager();
final IActivityManager mActivityManager;
@@ -422,7 +414,7 @@ public class WindowManagerService extends IWindowManager.Stub
* This is set when we have run out of memory, and will either be an empty
* list or contain windows that need to be force removed.
*/
- ArrayList<WindowState> mForceRemoves;
+ final ArrayList<WindowState> mForceRemoves = new ArrayList<>();
/**
* Windows that clients are waiting to have drawn.
@@ -564,6 +556,10 @@ public class WindowManagerService extends IWindowManager.Stub
WindowState mInputMethodWindow = null;
final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
+ /** Temporary list for comparison. Always clear this after use so we don't end up with
+ * orphaned windows references */
+ final ArrayList<WindowState> mTmpWindows = new ArrayList<>();
+
boolean mHardKeyboardAvailable;
boolean mShowImeWithHardKeyboard;
OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
@@ -593,7 +589,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
+ private final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
// If non-null, this is the currently visible window that is associated
// with the wallpaper.
@@ -622,13 +618,19 @@ public class WindowManagerService extends IWindowManager.Stub
static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
boolean mAnimateWallpaperWithTarget;
- // We give a wallpaper up to 1000ms to finish drawing before playing app transitions.
- static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 1000;
+ // We give a wallpaper up to 500ms to finish drawing before playing app transitions.
+ static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 500;
static final int WALLPAPER_DRAW_NORMAL = 0;
static final int WALLPAPER_DRAW_PENDING = 1;
static final int WALLPAPER_DRAW_TIMEOUT = 2;
int mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
+ // Set to the wallpaper window we would like to hide once the transition animations are done.
+ // This is useful in cases where we don't want the wallpaper to be hidden when the close app
+ // is a wallpaper target and is done animating out, but the opening app isn't a wallpaper
+ // target and isn't done animating in.
+ WindowState mDeferredHideWallpaper = null;
+
AppWindowToken mFocusedApp = null;
PowerManager mPowerManager;
@@ -703,17 +705,22 @@ public class WindowManagerService extends IWindowManager.Stub
final WindowAnimator mAnimator;
- SparseArray<Task> mTaskIdToTask = new SparseArray<Task>();
+ SparseArray<Task> mTaskIdToTask = new SparseArray<>();
/** All of the TaskStacks in the window manager, unordered. For an ordered list call
* DisplayContent.getStacks(). */
- SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>();
+ SparseArray<TaskStack> mStackIdToStack = new SparseArray<>();
private final PointerEventDispatcher mPointerEventDispatcher;
private WindowContentFrameStats mTempWindowRenderStats;
final class DragInputEventReceiver extends InputEventReceiver {
+ // Set, if stylus button was down at the start of the drag.
+ private boolean mStylusButtonDownAtStart;
+ // Indicates the first event to check for button state.
+ private boolean mIsStartEvent = true;
+
public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
}
@@ -729,6 +736,18 @@ public class WindowManagerService extends IWindowManager.Stub
boolean endDrag = false;
final float newX = motionEvent.getRawX();
final float newY = motionEvent.getRawY();
+ final boolean isStylusButtonDown =
+ (motionEvent.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS)
+ && (motionEvent.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0;
+
+ if (mIsStartEvent) {
+ if (isStylusButtonDown) {
+ // First event and the button was down, check for the button being
+ // lifted in the future, if that happens we'll drop the item.
+ mStylusButtonDownAtStart = true;
+ }
+ mIsStartEvent = false;
+ }
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN: {
@@ -738,9 +757,17 @@ public class WindowManagerService extends IWindowManager.Stub
} break;
case MotionEvent.ACTION_MOVE: {
- synchronized (mWindowMap) {
- // move the surface and tell the involved window(s) where we are
- mDragState.notifyMoveLw(newX, newY);
+ if (mStylusButtonDownAtStart && !isStylusButtonDown) {
+ if (DEBUG_DRAG) Slog.d(TAG, "Button no longer pressed; dropping at "
+ + newX + "," + newY);
+ synchronized (mWindowMap) {
+ endDrag = mDragState.notifyDropLw(newX, newY);
+ }
+ } else {
+ synchronized (mWindowMap) {
+ // move the surface and tell the involved window(s) where we are
+ mDragState.notifyMoveLw(newX, newY);
+ }
}
} break;
@@ -764,6 +791,8 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mWindowMap) {
mDragState.endDragLw();
}
+ mStylusButtonDownAtStart = false;
+ mIsStartEvent = true;
}
handled = true;
@@ -802,6 +831,35 @@ public class WindowManagerService extends IWindowManager.Stub
// For example, when this flag is true, there will be no wallpaper service.
final boolean mOnlyCore;
+ /** Listener to notify activity manager about app transitions. */
+ private final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
+ = new WindowManagerInternal.AppTransitionListener() {
+
+ @Override
+ public void onAppTransitionFinishedLocked(IBinder token) {
+ AppWindowToken atoken = findAppWindowToken(token);
+ if (atoken == null) {
+ return;
+ }
+ if (atoken.mLaunchTaskBehind) {
+ try {
+ mActivityManager.notifyLaunchTaskBehindComplete(atoken.token);
+ } catch (RemoteException e) {
+ }
+ atoken.mLaunchTaskBehind = false;
+ } else {
+ atoken.updateReportedVisibilityLocked();
+ if (atoken.mEnteringAnimation) {
+ atoken.mEnteringAnimation = false;
+ try {
+ mActivityManager.notifyEnterAnimationComplete(atoken.token);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+ };
+
public static WindowManagerService main(final Context context,
final InputManagerService im,
final boolean haveInputMethods, final boolean showBootMsgs,
@@ -824,9 +882,6 @@ public class WindowManagerService extends IWindowManager.Stub
WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
- mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
- * TYPE_LAYER_MULTIPLIER
- + TYPE_LAYER_OFFSET;
}
}, 0);
}
@@ -885,6 +940,7 @@ public class WindowManagerService extends IWindowManager.Stub
mScreenFrozenLock.setReferenceCounted(false);
mAppTransition = new AppTransition(context, mH);
+ mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
mActivityManager = ActivityManagerNative.getDefault();
mBatteryStats = BatteryStatsService.getService();
@@ -1719,7 +1775,7 @@ public class WindowManagerService extends IWindowManager.Stub
return true;
}
- final boolean isWallpaperVisible(WindowState wallpaperTarget) {
+ private boolean isWallpaperVisible(WindowState wallpaperTarget) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
+ (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
+ " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
@@ -1733,10 +1789,42 @@ public class WindowManagerService extends IWindowManager.Stub
|| mLowerWallpaperTarget != null;
}
- static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
- static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
+ void hideWallpapersLocked(final WindowState winGoingAway) {
+ if (mWallpaperTarget != null
+ && (mWallpaperTarget != winGoingAway || mLowerWallpaperTarget != null)) {
+ return;
+ }
+ if (mAppTransition.isRunning()) {
+ // Defer hiding the wallpaper when app transition is running until the animations
+ // are done.
+ mDeferredHideWallpaper = winGoingAway;
+ return;
+ }
- int adjustWallpaperWindowsLocked() {
+ final boolean wasDeferred = (mDeferredHideWallpaper == winGoingAway);
+ for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
+ final WindowToken token = mWallpaperTokens.get(i);
+ for (int j = token.windows.size() - 1; j >= 0; j--) {
+ final WindowState wallpaper = token.windows.get(j);
+ final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
+ if (!winAnimator.mLastHidden || wasDeferred) {
+ winAnimator.hide();
+ dispatchWallpaperVisibility(wallpaper, false);
+ final DisplayContent displayContent = wallpaper.getDisplayContent();
+ if (displayContent != null) {
+ displayContent.pendingLayoutChanges |=
+ WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+ }
+ }
+ }
+ if (DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, "Hiding wallpaper " + token
+ + " from " + winGoingAway + " target=" + mWallpaperTarget + " lower="
+ + mLowerWallpaperTarget + "\n" + Debug.getCallers(5, " "));
+ token.hidden = true;
+ }
+ }
+
+ boolean adjustWallpaperWindowsLocked() {
mInnerFields.mWallpaperMayChange = false;
boolean targetChanged = false;
@@ -1915,7 +2003,7 @@ public class WindowManagerService extends IWindowManager.Stub
// AND any starting window associated with it, AND below the
// maximum layer the policy allows for wallpapers.
while (foundI > 0) {
- WindowState wb = windows.get(foundI-1);
+ WindowState wb = windows.get(foundI - 1);
if (wb.mBaseLayer < maxLayer &&
wb.mAttachedWindow != foundW &&
(foundW.mAttachedWindow == null ||
@@ -1941,7 +2029,7 @@ public class WindowManagerService extends IWindowManager.Stub
} else {
// Okay i is the position immediately above the wallpaper. Look at
// what is below it for later.
- foundW = foundI > 0 ? windows.get(foundI-1) : null;
+ foundW = foundI > 0 ? windows.get(foundI - 1) : null;
}
if (visible) {
@@ -1963,44 +2051,37 @@ public class WindowManagerService extends IWindowManager.Stub
// Start stepping backwards from here, ensuring that our wallpaper windows
// are correctly placed.
- int changed = 0;
- int curTokenIndex = mWallpaperTokens.size();
- while (curTokenIndex > 0) {
- curTokenIndex--;
- WindowToken token = mWallpaperTokens.get(curTokenIndex);
+ boolean changed = false;
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ WindowToken token = mWallpaperTokens.get(curTokenNdx);
if (token.hidden == visible) {
if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
"Wallpaper token " + token + " hidden=" + !visible);
- changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
token.hidden = !visible;
- // Need to do a layout to ensure the wallpaper now has the
- // correct size.
+ // Need to do a layout to ensure the wallpaper now has the correct size.
getDefaultDisplayContentLocked().layoutNeeded = true;
}
- int curWallpaperIndex = token.windows.size();
- while (curWallpaperIndex > 0) {
- curWallpaperIndex--;
- WindowState wallpaper = token.windows.get(curWallpaperIndex);
+ final WindowList tokenWindows = token.windows;
+ for (int wallpaperNdx = tokenWindows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+ WindowState wallpaper = tokenWindows.get(wallpaperNdx);
if (visible) {
updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
}
- // First, make sure the client has the current visibility
- // state.
+ // First, make sure the client has the current visibility state.
dispatchWallpaperVisibility(wallpaper, visible);
- wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
+ wallpaper.mWinAnimator.mAnimLayer =
+ wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
+ wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
- // First, if this window is at the current index, then all
- // is well.
+ // First, if this window is at the current index, then all is well.
if (wallpaper == foundW) {
foundI--;
- foundW = foundI > 0
- ? windows.get(foundI-1) : null;
+ foundW = foundI > 0 ? windows.get(foundI - 1) : null;
continue;
}
@@ -2036,52 +2117,24 @@ public class WindowManagerService extends IWindowManager.Stub
windows.add(insertionIndex, wallpaper);
mWindowsChanged = true;
- changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
- }
- }
-
- /*
- final TaskStack targetStack =
- mWallpaperTarget == null ? null : mWallpaperTarget.getStack();
- if ((changed & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0 &&
- targetStack != null && !targetStack.isHomeStack()) {
- // If the wallpaper target is not on the home stack then make sure that all windows
- // from other non-home stacks are above the wallpaper.
- for (i = foundI - 1; i >= 0; --i) {
- WindowState win = windows.get(i);
- if (!win.isVisibleLw()) {
- continue;
- }
- final TaskStack winStack = win.getStack();
- if (winStack != null && !winStack.isHomeStack() && winStack != targetStack) {
- windows.remove(i);
- windows.add(foundI + 1, win);
- }
+ changed = true;
}
}
- */
- if (targetChanged && DEBUG_WALLPAPER_LIGHT) {
- Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
- + " lower=" + mLowerWallpaperTarget + " upper="
- + mUpperWallpaperTarget);
- }
+ if (targetChanged && DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, "New wallpaper: target="
+ + mWallpaperTarget + " lower=" + mLowerWallpaperTarget + " upper="
+ + mUpperWallpaperTarget);
return changed;
}
void setWallpaperAnimLayerAdjustmentLocked(int adj) {
- if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
- "Setting wallpaper layer adj to " + adj);
+ if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Setting wallpaper layer adj to " + adj);
mWallpaperAnimLayerAdjustment = adj;
- int curTokenIndex = mWallpaperTokens.size();
- while (curTokenIndex > 0) {
- curTokenIndex--;
- WindowToken token = mWallpaperTokens.get(curTokenIndex);
- int curWallpaperIndex = token.windows.size();
- while (curWallpaperIndex > 0) {
- curWallpaperIndex--;
- WindowState wallpaper = token.windows.get(curWallpaperIndex);
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
+ for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+ WindowState wallpaper = windows.get(wallpaperNdx);
wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
+ wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
@@ -2215,14 +2268,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- int curTokenIndex = mWallpaperTokens.size();
- while (curTokenIndex > 0) {
- curTokenIndex--;
- WindowToken token = mWallpaperTokens.get(curTokenIndex);
- int curWallpaperIndex = token.windows.size();
- while (curWallpaperIndex > 0) {
- curWallpaperIndex--;
- WindowState wallpaper = token.windows.get(curWallpaperIndex);
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
+ for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+ WindowState wallpaper = windows.get(wallpaperNdx);
if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
winAnimator.computeShownFrameLocked();
@@ -2237,12 +2286,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
/**
- * Check wallpaper for visiblity change and notify window if so.
+ * Check wallpaper for visibility change and notify window if so.
* @param wallpaper The wallpaper to test and notify.
* @param visible Current visibility.
*/
void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
- if (wallpaper.mWallpaperVisible != visible) {
+ // Only send notification if the visibility actually changed and we are not trying to hide
+ // the wallpaper when we are deferring hiding of the wallpaper.
+ if (wallpaper.mWallpaperVisible != visible
+ && (mDeferredHideWallpaper == null || visible)) {
wallpaper.mWallpaperVisible = visible;
try {
if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
@@ -2254,7 +2306,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- void updateWallpaperVisibilityLocked() {
+ private void updateWallpaperVisibilityLocked() {
final boolean visible = isWallpaperVisible(mWallpaperTarget);
final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
if (displayContent == null) {
@@ -2264,21 +2316,18 @@ public class WindowManagerService extends IWindowManager.Stub
final int dw = displayInfo.logicalWidth;
final int dh = displayInfo.logicalHeight;
- int curTokenIndex = mWallpaperTokens.size();
- while (curTokenIndex > 0) {
- curTokenIndex--;
- WindowToken token = mWallpaperTokens.get(curTokenIndex);
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ WindowToken token = mWallpaperTokens.get(curTokenNdx);
if (token.hidden == visible) {
token.hidden = !visible;
// Need to do a layout to ensure the wallpaper now has the
// correct size.
- getDefaultDisplayContentLocked().layoutNeeded = true;
+ displayContent.layoutNeeded = true;
}
- int curWallpaperIndex = token.windows.size();
- while (curWallpaperIndex > 0) {
- curWallpaperIndex--;
- WindowState wallpaper = token.windows.get(curWallpaperIndex);
+ final WindowList windows = token.windows;
+ for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+ WindowState wallpaper = windows.get(wallpaperNdx);
if (visible) {
updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
}
@@ -2299,7 +2348,6 @@ public class WindowManagerService extends IWindowManager.Stub
boolean reportNewConfig = false;
WindowState attachedWindow = null;
- WindowState win = null;
long origId;
final int type = attrs.type;
@@ -2436,7 +2484,7 @@ public class WindowManagerService extends IWindowManager.Stub
addToken = true;
}
- win = new WindowState(this, session, client, token,
+ WindowState win = new WindowState(this, session, client, token,
attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
@@ -2614,11 +2662,11 @@ public class WindowManagerService extends IWindowManager.Stub
if (win == null) {
return;
}
- removeWindowLocked(session, win);
+ removeWindowLocked(win);
}
}
- public void removeWindowLocked(Session session, WindowState win) {
+ void removeWindowLocked(WindowState win) {
if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Starting window removed " + win);
}
@@ -2692,7 +2740,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- removeWindowInnerLocked(session, win);
+ removeWindowInnerLocked(win);
// Removing a visible window will effect the computed orientation
// So just update orientation if needed.
if (wasVisible && updateOrientationFromAppTokensLocked(false)) {
@@ -2702,7 +2750,7 @@ public class WindowManagerService extends IWindowManager.Stub
Binder.restoreCallingIdentity(origId);
}
- void removeWindowInnerLocked(Session session, WindowState win) {
+ void removeWindowInnerLocked(WindowState win) {
if (win.mRemoved) {
// Nothing to do.
return;
@@ -2712,7 +2760,7 @@ public class WindowManagerService extends IWindowManager.Stub
WindowState cwin = win.mChildWindows.get(i);
Slog.w(TAG, "Force-removing child win " + cwin + " from container "
+ win);
- removeWindowInnerLocked(cwin.mSession, cwin);
+ removeWindowInnerLocked(cwin);
}
win.mRemoved = true;
@@ -2936,14 +2984,10 @@ public class WindowManagerService extends IWindowManager.Stub
if (window == mWallpaperTarget || window == mLowerWallpaperTarget
|| window == mUpperWallpaperTarget) {
boolean doWait = sync;
- int curTokenIndex = mWallpaperTokens.size();
- while (curTokenIndex > 0) {
- curTokenIndex--;
- WindowToken token = mWallpaperTokens.get(curTokenIndex);
- int curWallpaperIndex = token.windows.size();
- while (curWallpaperIndex > 0) {
- curWallpaperIndex--;
- WindowState wallpaper = token.windows.get(curWallpaperIndex);
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ final WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
+ for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+ WindowState wallpaper = windows.get(wallpaperNdx);
try {
wallpaper.mClient.dispatchWallpaperCommand(action,
x, y, z, extras, sync);
@@ -2962,37 +3006,6 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
- public void setUniverseTransformLocked(WindowState window, float alpha,
- float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
- Transformation transform = window.mWinAnimator.mUniverseTransform;
- transform.setAlpha(alpha);
- Matrix matrix = transform.getMatrix();
- matrix.getValues(mTmpFloats);
- mTmpFloats[Matrix.MTRANS_X] = offx;
- mTmpFloats[Matrix.MTRANS_Y] = offy;
- mTmpFloats[Matrix.MSCALE_X] = dsdx;
- mTmpFloats[Matrix.MSKEW_Y] = dtdx;
- mTmpFloats[Matrix.MSKEW_X] = dsdy;
- mTmpFloats[Matrix.MSCALE_Y] = dtdy;
- matrix.setValues(mTmpFloats);
- final DisplayContent displayContent = window.getDisplayContent();
- if (displayContent == null) {
- return;
- }
-
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
- final RectF dispRect = new RectF(0, 0,
- displayInfo.logicalWidth, displayInfo.logicalHeight);
- matrix.mapRect(dispRect);
- window.mGivenTouchableRegion.set(0, 0,
- displayInfo.logicalWidth, displayInfo.logicalHeight);
- window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
- (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
- window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
- displayContent.layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
- }
-
public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
synchronized (mWindowMap) {
if (mAccessibilityController != null) {
@@ -3417,6 +3430,7 @@ public class WindowManagerService extends IWindowManager.Stub
WindowState win = atoken.findMainWindow();
Rect containingFrame = new Rect(0, 0, width, height);
Rect contentInsets = new Rect();
+ Rect appFrame = new Rect(0, 0, width, height);
boolean isFullScreen = true;
if (win != null) {
if (win.mContainingFrame != null) {
@@ -3425,6 +3439,9 @@ public class WindowManagerService extends IWindowManager.Stub
if (win.mContentInsets != null) {
contentInsets.set(win.mContentInsets);
}
+ if (win.mFrame != null) {
+ appFrame.set(win.mFrame);
+ }
isFullScreen =
((win.mSystemUiVisibility & SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) ==
SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) ||
@@ -3438,8 +3455,8 @@ public class WindowManagerService extends IWindowManager.Stub
enter = false;
}
Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height,
- mCurConfiguration.orientation, containingFrame, contentInsets, isFullScreen,
- isVoiceInteraction);
+ mCurConfiguration.orientation, containingFrame, contentInsets, appFrame,
+ isFullScreen, isVoiceInteraction);
if (a != null) {
if (DEBUG_ANIM) {
RuntimeException e = null;
@@ -3625,13 +3642,13 @@ public class WindowManagerService extends IWindowManager.Stub
false /*updateInputWindows*/);
}
- if (delayed) {
- if (displayContent != null) {
- displayContent.mExitingTokens.add(wtoken);
- }
+ if (delayed && displayContent != null) {
+ displayContent.mExitingTokens.add(wtoken);
} else if (wtoken.windowType == TYPE_WALLPAPER) {
mWallpaperTokens.remove(wtoken);
}
+ } else if (wtoken.windowType == TYPE_WALLPAPER) {
+ mWallpaperTokens.remove(wtoken);
}
mInputMonitor.updateInputWindowsLw(true /*force*/);
@@ -3642,23 +3659,23 @@ public class WindowManagerService extends IWindowManager.Stub
Binder.restoreCallingIdentity(origId);
}
- private Task createTask(int taskId, int stackId, int userId, AppWindowToken atoken) {
- if (DEBUG_STACK) Slog.i(TAG, "createTask: taskId=" + taskId + " stackId=" + stackId
+ private Task createTaskLocked(int taskId, int stackId, int userId, AppWindowToken atoken) {
+ if (DEBUG_STACK) Slog.i(TAG, "createTaskLocked: taskId=" + taskId + " stackId=" + stackId
+ " atoken=" + atoken);
final TaskStack stack = mStackIdToStack.get(stackId);
if (stack == null) {
throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
}
EventLog.writeEvent(EventLogTags.WM_TASK_CREATED, taskId, stackId);
- Task task = new Task(atoken, stack, userId);
+ Task task = new Task(taskId, stack, userId, this);
mTaskIdToTask.put(taskId, task);
- stack.addTask(task, !atoken.mLaunchTaskBehind /* toTop */);
+ stack.addTask(task, !atoken.mLaunchTaskBehind /* toTop */, atoken.showForAllUsers);
return task;
}
@Override
public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
- int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
+ int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int userId,
int configChanges, boolean voiceInteraction, boolean launchTaskBehind) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addAppToken()")) {
@@ -3687,9 +3704,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
atoken = new AppWindowToken(this, token, voiceInteraction);
atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
- atoken.groupId = taskId;
atoken.appFullscreen = fullscreen;
- atoken.showWhenLocked = showWhenLocked;
+ atoken.showForAllUsers = showForAllUsers;
atoken.requestedOrientation = requestedOrientation;
atoken.layoutConfigChanges = (configChanges &
(ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0;
@@ -3699,10 +3715,9 @@ public class WindowManagerService extends IWindowManager.Stub
Task task = mTaskIdToTask.get(taskId);
if (task == null) {
- createTask(taskId, stackId, userId, atoken);
- } else {
- task.addAppToken(addPos, atoken);
+ task = createTaskLocked(taskId, stackId, userId, atoken);
}
+ task.addAppToken(addPos, atoken);
mTokenMap.put(token.asBinder(), atoken);
@@ -3715,28 +3730,27 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public void setAppGroupId(IBinder token, int groupId) {
+ public void setAppTask(IBinder token, int taskId) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
- "setAppGroupId()")) {
+ "setAppTask()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized(mWindowMap) {
final AppWindowToken atoken = findAppWindowToken(token);
if (atoken == null) {
- Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
+ Slog.w(TAG, "Attempted to set task id of non-existing app token: " + token);
return;
}
- final Task oldTask = mTaskIdToTask.get(atoken.groupId);
+ final Task oldTask = atoken.mTask;
oldTask.removeAppToken(atoken);
- atoken.groupId = groupId;
- Task newTask = mTaskIdToTask.get(groupId);
+ Task newTask = mTaskIdToTask.get(taskId);
if (newTask == null) {
- newTask = createTask(groupId, oldTask.mStack.mStackId, oldTask.mUserId, atoken);
- } else {
- newTask.mAppTokens.add(atoken);
+ newTask =
+ createTaskLocked(taskId, oldTask.mStack.mStackId, oldTask.mUserId, atoken);
}
+ newTask.addAppToken(Integer.MAX_VALUE /* at top */, atoken);
}
}
@@ -3755,10 +3769,8 @@ public class WindowManagerService extends IWindowManager.Stub
} else {
// TODO(multidisplay): Change to the correct display.
final WindowList windows = getDefaultWindowListLocked();
- int pos = windows.size() - 1;
- while (pos >= 0) {
+ for (int pos = windows.size() - 1; pos >= 0; --pos) {
WindowState win = windows.get(pos);
- pos--;
if (win.mAppToken != null) {
// We hit an application window. so the orientation will be determined by the
// app window. No point in continuing further.
@@ -3858,14 +3870,12 @@ public class WindowManagerService extends IWindowManager.Stub
// to use the orientation behind it, then just take whatever
// orientation it has and ignores whatever is under it.
lastFullscreen = atoken.appFullscreen;
- if (lastFullscreen
- && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
+ if (lastFullscreen && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
+ " -- full screen, return " + or);
return or;
}
- // If this application has requested an explicit orientation,
- // then use it.
+ // If this application has requested an explicit orientation, then use it.
if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
&& or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
@@ -3904,6 +3914,9 @@ public class WindowManagerService extends IWindowManager.Stub
private Configuration updateOrientationFromAppTokensLocked(
Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
+ if (!mDisplayReady) {
+ return null;
+ }
Configuration config = null;
if (updateOrientationFromAppTokensLocked(false)) {
@@ -3922,20 +3935,19 @@ public class WindowManagerService extends IWindowManager.Stub
// the value of the previous configuration.
mTempConfiguration.setToDefaults();
mTempConfiguration.fontScale = currentConfig.fontScale;
- if (computeScreenConfigurationLocked(mTempConfiguration)) {
- if (currentConfig.diff(mTempConfiguration) != 0) {
- mWaitingForConfig = true;
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
- displayContent.layoutNeeded = true;
- int anim[] = new int[2];
- if (displayContent.isDimming()) {
- anim[0] = anim[1] = 0;
- } else {
- mPolicy.selectRotationAnimationLw(anim);
- }
- startFreezingDisplayLocked(false, anim[0], anim[1]);
- config = new Configuration(mTempConfiguration);
+ computeScreenConfigurationLocked(mTempConfiguration);
+ if (currentConfig.diff(mTempConfiguration) != 0) {
+ mWaitingForConfig = true;
+ final DisplayContent displayContent = getDefaultDisplayContentLocked();
+ displayContent.layoutNeeded = true;
+ int anim[] = new int[2];
+ if (displayContent.isDimming()) {
+ anim[0] = anim[1] = 0;
+ } else {
+ mPolicy.selectRotationAnimationLw(anim);
}
+ startFreezingDisplayLocked(false, anim[0], anim[1]);
+ config = new Configuration(mTempConfiguration);
}
}
@@ -4046,7 +4058,7 @@ public class WindowManagerService extends IWindowManager.Stub
void setFocusedStackFrame() {
final TaskStack stack;
if (mFocusedApp != null) {
- Task task = mTaskIdToTask.get(mFocusedApp.groupId);
+ final Task task = mFocusedApp.mTask;
stack = task.mStack;
final DisplayContent displayContent = task.getDisplayContent();
if (displayContent != null) {
@@ -4055,20 +4067,7 @@ public class WindowManagerService extends IWindowManager.Stub
} else {
stack = null;
}
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedStackFrame");
- SurfaceControl.openTransaction();
- try {
- if (stack == null) {
- mFocusedStackFrame.setVisibility(false);
- } else {
- mFocusedStackFrame.setBounds(stack);
- final boolean multipleStacks = !stack.isFullscreen();
- mFocusedStackFrame.setVisibility(multipleStacks);
- }
- } finally {
- SurfaceControl.closeTransaction();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedStackFrame");
- }
+ mFocusedStackFrame.setVisibility(stack);
}
@Override
@@ -4179,6 +4178,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void overridePendingAppTransitionClipReveal(int startX, int startY,
+ int startWidth, int startHeight) {
+ synchronized(mWindowMap) {
+ mAppTransition.overridePendingAppTransitionClipReveal(startX, startY, startWidth,
+ startHeight);
+ }
+ }
+
+ @Override
public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
int startY, IRemoteCallback startedCallback, boolean scaleUp) {
synchronized(mWindowMap) {
@@ -4212,8 +4220,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
synchronized(mWindowMap) {
- if (DEBUG_APP_TRANSITIONS) Slog.w(TAG, "Execute app transition: " + mAppTransition,
- new RuntimeException("here").fillInStackTrace());
+ if (DEBUG_APP_TRANSITIONS) Slog.w(TAG, "Execute app transition: " + mAppTransition
+ + " Callers=" + Debug.getCallers(5));
if (mAppTransition.isTransitionSet()) {
mAppTransition.setReady();
final long origId = Binder.clearCallingIdentity();
@@ -4649,8 +4657,12 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) Slog.v(TAG, "setAppVisibility(" +
token + ", visible=" + visible + "): " + mAppTransition +
" hidden=" + wtoken.hidden + " hiddenRequested=" +
- wtoken.hiddenRequested, HIDE_STACK_CRAWLS ?
- null : new RuntimeException("here").fillInStackTrace());
+ wtoken.hiddenRequested + " Callers=" + Debug.getCallers(6));
+
+ mOpeningApps.remove(wtoken);
+ mClosingApps.remove(wtoken);
+ wtoken.waitingToShow = wtoken.waitingToHide = false;
+ wtoken.hiddenRequested = !visible;
mOpeningApps.remove(wtoken);
mClosingApps.remove(wtoken);
@@ -4843,17 +4855,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- void removeAppFromTaskLocked(AppWindowToken wtoken) {
- wtoken.removeAllWindows();
-
- final Task task = mTaskIdToTask.get(wtoken.groupId);
- if (task != null) {
- if (!task.removeAppToken(wtoken)) {
- Slog.e(TAG, "removeAppFromTaskLocked: token=" + wtoken + " not found.");
- }
- }
- }
-
@Override
public void removeAppToken(IBinder token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
@@ -4888,20 +4889,20 @@ public class WindowManagerService extends IWindowManager.Stub
+ " animating=" + wtoken.mAppAnimator.animating);
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "removeAppToken: "
+ wtoken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
- final TaskStack stack = mTaskIdToTask.get(wtoken.groupId).mStack;
+ final TaskStack stack = wtoken.mTask.mStack;
if (delayed && !wtoken.allAppWindows.isEmpty()) {
// set the token aside because it has an active animation to be finished
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
"removeAppToken make exiting: " + wtoken);
stack.mExitingAppTokens.add(wtoken);
- wtoken.mDeferRemoval = true;
+ wtoken.mIsExiting = true;
} else {
// Make sure there is no animation running on this token,
// so any windows associated with it will be removed as
// soon as their animations are complete
wtoken.mAppAnimator.clearAnimation();
wtoken.mAppAnimator.animating = false;
- removeAppFromTaskLocked(wtoken);
+ wtoken.removeAppFromTaskLocked();
}
wtoken.removed = true;
@@ -4944,39 +4945,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
- WindowList windows = token.windows;
- final int NW = windows.size();
- if (NW > 0) {
- mWindowsChanged = true;
- }
- int targetDisplayId = -1;
- Task targetTask = mTaskIdToTask.get(token.appWindowToken.groupId);
- if (targetTask != null) {
- DisplayContent targetDisplayContent = targetTask.getDisplayContent();
- if (targetDisplayContent != null) {
- targetDisplayId = targetDisplayContent.getDisplayId();
- }
- }
- for (int i = 0; i < NW; i++) {
- WindowState win = windows.get(i);
- if (targetDisplayId != -1 && win.getDisplayId() != targetDisplayId) {
- continue;
- }
- if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
- win.getWindowList().remove(win);
- int j = win.mChildWindows.size();
- while (j > 0) {
- j--;
- WindowState cwin = win.mChildWindows.get(j);
- if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
- "Tmp removing child window " + cwin);
- cwin.getWindowList().remove(cwin);
- }
- }
- return NW > 0;
- }
-
void dumpAppTokensLocked() {
final int numStacks = mStackIdToStack.size();
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
@@ -4986,7 +4954,7 @@ public class WindowManagerService extends IWindowManager.Stub
final int numTasks = tasks.size();
for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
final Task task = tasks.get(taskNdx);
- Slog.v(TAG, " Task #" + task.taskId + " activities from bottom to top:");
+ Slog.v(TAG, " Task #" + task.mTaskId + " activities from bottom to top:");
AppTokenList tokens = task.mAppTokens;
final int numTokens = tokens.size();
for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
@@ -5008,90 +4976,20 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- private int findAppWindowInsertionPointLocked(AppWindowToken target) {
- final int taskId = target.groupId;
- Task targetTask = mTaskIdToTask.get(taskId);
- if (targetTask == null) {
- Slog.w(TAG, "findAppWindowInsertionPointLocked: no Task for " + target + " taskId="
- + taskId);
- return 0;
- }
- DisplayContent displayContent = targetTask.getDisplayContent();
- if (displayContent == null) {
- Slog.w(TAG, "findAppWindowInsertionPointLocked: no DisplayContent for " + target);
- return 0;
- }
- final WindowList windows = displayContent.getWindowList();
- final int NW = windows.size();
-
- boolean found = false;
- final ArrayList<Task> tasks = displayContent.getTasks();
- for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
- final Task task = tasks.get(taskNdx);
- if (!found && task.taskId != taskId) {
- continue;
- }
- AppTokenList tokens = task.mAppTokens;
- for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
- final AppWindowToken wtoken = tokens.get(tokenNdx);
- if (!found && wtoken == target) {
- found = true;
- }
- if (found) {
- // Find the first app token below the new position that has
- // a window displayed.
- if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows in " + wtoken.token);
- if (wtoken.sendingToBottom) {
- if (DEBUG_REORDER) Slog.v(TAG, "Skipping token -- currently sending to bottom");
- continue;
- }
- for (int i = wtoken.windows.size() - 1; i >= 0; --i) {
- WindowState win = wtoken.windows.get(i);
- for (int j = win.mChildWindows.size() - 1; j >= 0; --j) {
- WindowState cwin = win.mChildWindows.get(j);
- if (cwin.mSubLayer >= 0) {
- for (int pos = NW - 1; pos >= 0; pos--) {
- if (windows.get(pos) == cwin) {
- if (DEBUG_REORDER) Slog.v(TAG,
- "Found child win @" + (pos + 1));
- return pos + 1;
- }
- }
- }
- }
- for (int pos = NW - 1; pos >= 0; pos--) {
- if (windows.get(pos) == win) {
- if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos + 1));
- return pos + 1;
- }
- }
- }
- }
- }
- }
- // Never put an app window underneath wallpaper.
- for (int pos = NW - 1; pos >= 0; pos--) {
- if (windows.get(pos).mIsWallpaper) {
- if (DEBUG_REORDER) Slog.v(TAG, "Found wallpaper @" + pos);
- return pos + 1;
- }
- }
- return 0;
- }
-
private final int reAddWindowLocked(int index, WindowState win) {
final WindowList windows = win.getWindowList();
+ // Adding child windows relies on mChildWindows being ordered by mSubLayer.
final int NCW = win.mChildWindows.size();
- boolean added = false;
+ boolean winAdded = false;
for (int j=0; j<NCW; j++) {
WindowState cwin = win.mChildWindows.get(j);
- if (!added && cwin.mSubLayer >= 0) {
+ if (!winAdded && cwin.mSubLayer >= 0) {
if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
+ index + ": " + cwin);
win.mRebuilding = false;
windows.add(index, win);
index++;
- added = true;
+ winAdded = true;
}
if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
+ index + ": " + cwin);
@@ -5099,7 +4997,7 @@ public class WindowManagerService extends IWindowManager.Stub
windows.add(index, cwin);
index++;
}
- if (!added) {
+ if (!winAdded) {
if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
+ index + ": " + win);
win.mRebuilding = false;
@@ -5124,41 +5022,40 @@ public class WindowManagerService extends IWindowManager.Stub
return index;
}
- void tmpRemoveTaskWindowsLocked(Task task) {
- AppTokenList tokens = task.mAppTokens;
- for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
- tmpRemoveAppWindowsLocked(tokens.get(tokenNdx));
- }
- }
void moveStackWindowsLocked(DisplayContent displayContent) {
- // First remove all of the windows from the list.
- final ArrayList<Task> tasks = displayContent.getTasks();
- final int numTasks = tasks.size();
- for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
- tmpRemoveTaskWindowsLocked(tasks.get(taskNdx));
- }
+ final WindowList windows = displayContent.getWindowList();
+ mTmpWindows.addAll(windows);
- // And now add them back at the correct place.
- // Where to start adding?
- for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
- AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
- final int numTokens = tokens.size();
- if (numTokens == 0) {
- continue;
- }
- int pos = findAppWindowInsertionPointLocked(tokens.get(0));
- for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
- final AppWindowToken wtoken = tokens.get(tokenNdx);
- if (wtoken != null) {
- final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
- if (newPos != pos) {
- displayContent.layoutNeeded = true;
- }
- pos = newPos;
- }
+ rebuildAppWindowListLocked(displayContent);
+
+ // Set displayContent.layoutNeeded if window order changed.
+ final int tmpSize = mTmpWindows.size();
+ final int winSize = windows.size();
+ int tmpNdx = 0, winNdx = 0;
+ while (tmpNdx < tmpSize && winNdx < winSize) {
+ // Skip over all exiting windows, they've been moved out of order.
+ WindowState tmp;
+ do {
+ tmp = mTmpWindows.get(tmpNdx++);
+ } while (tmpNdx < tmpSize && tmp.mAppToken != null && tmp.mAppToken.mIsExiting);
+
+ WindowState win;
+ do {
+ win = windows.get(winNdx++);
+ } while (winNdx < winSize && win.mAppToken != null && win.mAppToken.mIsExiting);
+
+ if (tmp != win) {
+ // Window order changed.
+ displayContent.layoutNeeded = true;
+ break;
}
}
+ if (tmpNdx != winNdx) {
+ // One list was different from the other.
+ displayContent.layoutNeeded = true;
+ }
+ mTmpWindows.clear();
if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
false /*updateInputWindows*/)) {
@@ -5281,30 +5178,6 @@ public class WindowManagerService extends IWindowManager.Stub
mStackIdToStack.remove(stackId);
}
- void removeTaskLocked(Task task) {
- final int taskId = task.taskId;
- final TaskStack stack = task.mStack;
- if (!task.mAppTokens.isEmpty() && stack.isAnimating()) {
- if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + taskId);
- task.mDeferRemoval = true;
- return;
- }
- if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + taskId);
- EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask");
- task.mDeferRemoval = false;
- stack.removeTask(task);
- mTaskIdToTask.delete(task.taskId);
-
- final ArrayList<AppWindowToken> exitingApps = stack.mExitingAppTokens;
- for (int appNdx = exitingApps.size() - 1; appNdx >= 0; --appNdx) {
- final AppWindowToken wtoken = exitingApps.get(appNdx);
- if (wtoken.groupId == taskId) {
- wtoken.mDeferRemoval = false;
- exitingApps.remove(appNdx);
- }
- }
- }
-
public void removeTask(int taskId) {
synchronized (mWindowMap) {
Task task = mTaskIdToTask.get(taskId);
@@ -5312,7 +5185,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);
return;
}
- removeTaskLocked(task);
+ task.removeLocked();
}
}
@@ -5322,6 +5195,7 @@ public class WindowManagerService extends IWindowManager.Stub
+ " to " + (toTop ? "top" : "bottom"));
Task task = mTaskIdToTask.get(taskId);
if (task == null) {
+ if (DEBUG_STACK) Slog.i(TAG, "addTask: could not find taskId=" + taskId);
return;
}
TaskStack stack = mStackIdToStack.get(stackId);
@@ -5332,7 +5206,33 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- public void resizeStack(int stackId, Rect bounds) {
+ public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
+ synchronized (mWindowMap) {
+ if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: moving taskId=" + taskId
+ + " to stackId=" + stackId + " at " + (toTop ? "top" : "bottom"));
+ Task task = mTaskIdToTask.get(taskId);
+ if (task == null) {
+ if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: could not find taskId=" + taskId);
+ return;
+ }
+ TaskStack stack = mStackIdToStack.get(stackId);
+ if (stack == null) {
+ if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: could not find stackId=" + stackId);
+ return;
+ }
+ task.moveTaskToStack(stack, toTop);
+ final DisplayContent displayContent = stack.getDisplayContent();
+ displayContent.layoutNeeded = true;
+ performLayoutAndPlaceSurfacesLocked();
+ }
+ }
+
+ /**
+ * Re-sizes the specified stack and its containing windows.
+ * Returns a {@link Configuration} object that contains configurations settings
+ * that should be overridden due to the operation.
+ */
+ public Configuration resizeStack(int stackId, Rect bounds) {
synchronized (mWindowMap) {
final TaskStack stack = mStackIdToStack.get(stackId);
if (stack == null) {
@@ -5344,6 +5244,7 @@ public class WindowManagerService extends IWindowManager.Stub
stack.getDisplayContent().layoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
}
+ return new Configuration(stack.mOverrideConfig);
}
}
@@ -5356,6 +5257,44 @@ public class WindowManagerService extends IWindowManager.Stub
bounds.setEmpty();
}
+ /** Returns the id of an application (non-home stack) stack that match the input bounds.
+ * -1 if no stack matches.*/
+ public int getStackIdWithBounds(Rect bounds) {
+ Rect stackBounds = new Rect();
+ synchronized (mWindowMap) {
+ for (int i = mStackIdToStack.size() - 1; i >= 0; --i) {
+ TaskStack stack = mStackIdToStack.valueAt(i);
+ if (stack.mStackId != HOME_STACK_ID) {
+ stack.getBounds(stackBounds);
+ if (stackBounds.equals(bounds)) {
+ return stack.mStackId;
+ }
+ }
+ }
+ }
+ return -1;
+ }
+
+ /** Forces the stack to fullscreen if input is true, else un-forces the stack from fullscreen.
+ * Returns a {@link Configuration} object that contains configurations settings
+ * that should be overridden due to the operation.
+ */
+ public Configuration forceStackToFullscreen(int stackId, boolean forceFullscreen) {
+ synchronized (mWindowMap) {
+ final TaskStack stack = mStackIdToStack.get(stackId);
+ if (stack == null) {
+ throw new IllegalArgumentException("resizeStack: stackId " + stackId
+ + " not found.");
+ }
+ if (stack.forceFullscreen(forceFullscreen)) {
+ stack.resizeWindows();
+ stack.getDisplayContent().layoutNeeded = true;
+ performLayoutAndPlaceSurfacesLocked();
+ }
+ return new Configuration(stack.mOverrideConfig);
+ }
+ }
+
// -------------------------------------------------------------
// Misc IWindowSession methods
// -------------------------------------------------------------
@@ -5716,7 +5655,7 @@ public class WindowManagerService extends IWindowManager.Stub
final int numDisplays = mDisplayContents.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- displayContent.switchUserStacks(newUserId);
+ displayContent.switchUserStacks();
rebuildAppWindowListLocked(displayContent);
}
performLayoutAndPlaceSurfacesLocked();
@@ -6145,26 +6084,57 @@ public class WindowManagerService extends IWindowManager.Stub
* Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
* In portrait mode, it grabs the upper region of the screen based on the vertical dimension
* of the target image.
+ */
+ @Override
+ public boolean requestAssistScreenshot(final IAssistScreenshotReceiver receiver) {
+ if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,
+ "requestAssistScreenshot()")) {
+ throw new SecurityException("Requires READ_FRAME_BUFFER permission");
+ }
+
+ FgThread.getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ Bitmap bm = screenshotApplicationsInner(null, Display.DEFAULT_DISPLAY, -1, -1,
+ true);
+ try {
+ receiver.send(bm);
+ } catch (RemoteException e) {
+ }
+ }
+ });
+
+ return true;
+ }
+
+ /**
+ * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
+ * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
+ * of the target image.
*
* @param displayId the Display to take a screenshot of.
* @param width the width of the target bitmap
* @param height the height of the target bitmap
- * @param force565 if true the returned bitmap will be RGB_565, otherwise it
- * will be the same config as the surface
*/
@Override
- public Bitmap screenshotApplications(IBinder appToken, int displayId, int width,
- int height, boolean force565) {
+ public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height) {
if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,
"screenshotApplications()")) {
throw new SecurityException("Requires READ_FRAME_BUFFER permission");
}
+ return screenshotApplicationsInner(appToken, displayId, width, height, false);
+ }
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
- if (displayContent == null) {
- if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
- + ": returning null. No Display for displayId=" + displayId);
- return null;
+ Bitmap screenshotApplicationsInner(IBinder appToken, int displayId, int width, int height,
+ boolean includeFullDisplay) {
+ final DisplayContent displayContent;
+ synchronized(mWindowMap) {
+ displayContent = getDisplayContentLocked(displayId);
+ if (displayContent == null) {
+ if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
+ + ": returning null. No Display for displayId=" + displayId);
+ return null;
+ }
}
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
int dw = displayInfo.logicalWidth;
@@ -6181,9 +6151,6 @@ public class WindowManagerService extends IWindowManager.Stub
final Rect frame = new Rect();
final Rect stackBounds = new Rect();
- float scale = 0;
- int rot = Surface.ROTATION_0;
-
boolean screenshotReady;
int minLayer;
if (appToken == null) {
@@ -6264,7 +6231,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
// Don't include wallpaper in bounds calculation
- if (!ws.mIsWallpaper) {
+ if (!includeFullDisplay && !ws.mIsWallpaper) {
final Rect wf = ws.mFrame;
final Rect cr = ws.mContentInsets;
int left = wf.left + cr.left;
@@ -6318,8 +6285,21 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
- // Constrain frame to the screen size.
- frame.intersect(0, 0, dw, dh);
+ if (!includeFullDisplay) {
+ // Constrain frame to the screen size.
+ frame.intersect(0, 0, dw, dh);
+ } else {
+ // Caller just wants entire display.
+ frame.set(0, 0, dw, dh);
+ }
+
+
+ if (width < 0) {
+ width = frame.width();
+ }
+ if (height < 0) {
+ height = frame.height();
+ }
// Tell surface flinger what part of the image to crop. Take the top
// right part of the application, and crop the larger dimension to fit.
@@ -6333,7 +6313,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
// The screenshot API does not apply the current screen rotation.
- rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
+ int rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
@@ -6596,13 +6576,12 @@ public class WindowManagerService extends IWindowManager.Stub
screenRotationAnimation =
mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
- // We need to update our screen size information to match the new
- // rotation. Note that this is redundant with the later call to
- // sendNewConfiguration() that must be called after this function
- // returns... however we need to do the screen size part of that
- // before then so we have the correct size to use when initializing
- // the rotation animation for the new rotation.
- computeScreenConfigurationLocked(null);
+ // We need to update our screen size information to match the new rotation. If the rotation
+ // has actually changed then this method will return true and, according to the comment at
+ // the top of the method, the caller is obligated to call computeNewConfigurationLocked().
+ // By updating the Display info here it will be available to
+ // computeScreenConfigurationLocked later.
+ updateDisplayAndOrientationLocked();
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
if (!inTransaction) {
@@ -7151,9 +7130,11 @@ public class WindowManagerService extends IWindowManager.Stub
public Configuration computeNewConfiguration() {
synchronized (mWindowMap) {
+ if (!mDisplayReady) {
+ return null;
+ }
Configuration config = computeNewConfigurationLocked();
- if (config == null && mWaitingForConfig) {
- // Nothing changed but we are waiting for something... stop that!
+ if (mWaitingForConfig) {
mWaitingForConfig = false;
mLastFinishedFreezeSource = "new-config";
performLayoutAndPlaceSurfacesLocked();
@@ -7165,9 +7146,7 @@ public class WindowManagerService extends IWindowManager.Stub
Configuration computeNewConfigurationLocked() {
Configuration config = new Configuration();
config.fontScale = 0;
- if (!computeScreenConfigurationLocked(config)) {
- return null;
- }
+ computeScreenConfigurationLocked(config);
return config;
}
@@ -7274,11 +7253,8 @@ public class WindowManagerService extends IWindowManager.Stub
return sw;
}
- boolean computeScreenConfigurationLocked(Configuration config) {
- if (!mDisplayReady) {
- return false;
- }
-
+ /** Do not call if mDisplayReady == false */
+ DisplayInfo updateDisplayAndOrientationLocked() {
// TODO(multidisplay): For now, apply Configuration to main screen only.
final DisplayContent displayContent = getDefaultDisplayContentLocked();
@@ -7308,11 +7284,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- if (config != null) {
- config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
- Configuration.ORIENTATION_LANDSCAPE;
- }
-
// Update application display metrics.
final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
@@ -7327,97 +7298,113 @@ public class WindowManagerService extends IWindowManager.Stub
displayInfo.getLogicalMetrics(mRealDisplayMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
displayInfo.getAppMetrics(mDisplayMetrics);
+ if (displayContent.mDisplayScalingDisabled) {
+ displayInfo.flags |= Display.FLAG_SCALING_DISABLED;
+ } else {
+ displayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
+ }
+
mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
displayContent.getDisplayId(), displayInfo);
+
displayContent.mBaseDisplayRect.set(0, 0, dw, dh);
}
if (false) {
Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
}
- final DisplayMetrics dm = mDisplayMetrics;
- mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
+ mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(mDisplayMetrics,
mCompatDisplayMetrics);
+ return displayInfo;
+ }
- if (config != null) {
- config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
- / dm.density);
- config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
- / dm.density);
- computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
-
- config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
- config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
- config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
- config.densityDpi = displayContent.mBaseDisplayDensity;
-
- // Update the configuration based on available input devices, lid switch,
- // and platform configuration.
- config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
- config.keyboard = Configuration.KEYBOARD_NOKEYS;
- config.navigation = Configuration.NAVIGATION_NONAV;
-
- int keyboardPresence = 0;
- int navigationPresence = 0;
- final InputDevice[] devices = mInputManager.getInputDevices();
- final int len = devices.length;
- for (int i = 0; i < len; i++) {
- InputDevice device = devices[i];
- if (!device.isVirtual()) {
- final int sources = device.getSources();
- final int presenceFlag = device.isExternal() ?
- WindowManagerPolicy.PRESENCE_EXTERNAL :
- WindowManagerPolicy.PRESENCE_INTERNAL;
-
- if (mIsTouchDevice) {
- if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
- InputDevice.SOURCE_TOUCHSCREEN) {
- config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
- }
- } else {
- config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
- }
+ /** Do not call if mDisplayReady == false */
+ void computeScreenConfigurationLocked(Configuration config) {
+ final DisplayInfo displayInfo = updateDisplayAndOrientationLocked();
- if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
- config.navigation = Configuration.NAVIGATION_TRACKBALL;
- navigationPresence |= presenceFlag;
- } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
- && config.navigation == Configuration.NAVIGATION_NONAV) {
- config.navigation = Configuration.NAVIGATION_DPAD;
- navigationPresence |= presenceFlag;
+ final int dw = displayInfo.logicalWidth;
+ final int dh = displayInfo.logicalHeight;
+ config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
+ Configuration.ORIENTATION_LANDSCAPE;
+ config.screenWidthDp =
+ (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation) / mDisplayMetrics.density);
+ config.screenHeightDp =
+ (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation) / mDisplayMetrics.density);
+ final boolean rotated = (mRotation == Surface.ROTATION_90
+ || mRotation == Surface.ROTATION_270);
+ computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, mDisplayMetrics.density,
+ config);
+
+ config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
+ config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
+ config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated,
+ mDisplayMetrics, dw, dh);
+ config.densityDpi = displayInfo.logicalDensityDpi;
+
+ // Update the configuration based on available input devices, lid switch,
+ // and platform configuration.
+ config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
+ config.keyboard = Configuration.KEYBOARD_NOKEYS;
+ config.navigation = Configuration.NAVIGATION_NONAV;
+
+ int keyboardPresence = 0;
+ int navigationPresence = 0;
+ final InputDevice[] devices = mInputManager.getInputDevices();
+ final int len = devices.length;
+ for (int i = 0; i < len; i++) {
+ InputDevice device = devices[i];
+ if (!device.isVirtual()) {
+ final int sources = device.getSources();
+ final int presenceFlag = device.isExternal() ?
+ WindowManagerPolicy.PRESENCE_EXTERNAL :
+ WindowManagerPolicy.PRESENCE_INTERNAL;
+
+ if (mIsTouchDevice) {
+ if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
+ InputDevice.SOURCE_TOUCHSCREEN) {
+ config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
}
+ } else {
+ config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
+ }
- if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
- config.keyboard = Configuration.KEYBOARD_QWERTY;
- keyboardPresence |= presenceFlag;
- }
+ if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
+ config.navigation = Configuration.NAVIGATION_TRACKBALL;
+ navigationPresence |= presenceFlag;
+ } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
+ && config.navigation == Configuration.NAVIGATION_NONAV) {
+ config.navigation = Configuration.NAVIGATION_DPAD;
+ navigationPresence |= presenceFlag;
}
- }
- if (config.navigation == Configuration.NAVIGATION_NONAV && mHasPermanentDpad) {
- config.navigation = Configuration.NAVIGATION_DPAD;
- navigationPresence |= WindowManagerPolicy.PRESENCE_INTERNAL;
+ if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
+ config.keyboard = Configuration.KEYBOARD_QWERTY;
+ keyboardPresence |= presenceFlag;
+ }
}
+ }
- // Determine whether a hard keyboard is available and enabled.
- boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
- if (hardKeyboardAvailable != mHardKeyboardAvailable) {
- mHardKeyboardAvailable = hardKeyboardAvailable;
- mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
- mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
- }
- if (mShowImeWithHardKeyboard) {
- config.keyboard = Configuration.KEYBOARD_NOKEYS;
- }
+ if (config.navigation == Configuration.NAVIGATION_NONAV && mHasPermanentDpad) {
+ config.navigation = Configuration.NAVIGATION_DPAD;
+ navigationPresence |= WindowManagerPolicy.PRESENCE_INTERNAL;
+ }
- // Let the policy update hidden states.
- config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
- config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
- config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
- mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
+ // Determine whether a hard keyboard is available and enabled.
+ boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
+ if (hardKeyboardAvailable != mHardKeyboardAvailable) {
+ mHardKeyboardAvailable = hardKeyboardAvailable;
+ mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
+ mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
+ }
+ if (mShowImeWithHardKeyboard) {
+ config.keyboard = Configuration.KEYBOARD_NOKEYS;
}
- return true;
+ // Let the policy update hidden states.
+ config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
+ config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
+ config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
+ mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
}
public boolean isHardKeyboardAvailable() {
@@ -7488,7 +7475,7 @@ public class WindowManagerService extends IWindowManager.Stub
outSurface.copyFrom(surface);
final IBinder winBinder = window.asBinder();
token = new Binder();
- mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
+ mDragState = new DragState(this, token, surface, flags, winBinder);
token = mDragState.mToken = new Binder();
// 5 second timeout for this window to actually begin the drag
@@ -7616,7 +7603,7 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized(mWindowMap) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
- readForcedDisplaySizeAndDensityLocked(displayContent);
+ readForcedDisplayPropertiesLocked(displayContent);
mDisplayReady = true;
}
@@ -8164,16 +8151,16 @@ public class WindowManagerService extends IWindowManager.Stub
break;
case TAP_OUTSIDE_STACK: {
-// int stackId;
-// synchronized (mWindowMap) {
-// stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2);
-// }
-// if (stackId >= 0) {
-// try {
-// mActivityManager.setFocusedStack(stackId);
-// } catch (RemoteException e) {
-// }
-// }
+ int stackId;
+ synchronized (mWindowMap) {
+ stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2);
+ }
+ if (stackId >= 0) {
+ try {
+ mActivityManager.setFocusedStack(stackId);
+ } catch (RemoteException e) {
+ }
+ }
}
break;
case NOTIFY_ACTIVITY_DRAWN:
@@ -8389,7 +8376,47 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
+ @Override
+ public void setForcedDisplayScalingMode(int displayId, int mode) {
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
+ PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Must hold permission " +
+ android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ }
+ if (displayId != Display.DEFAULT_DISPLAY) {
+ throw new IllegalArgumentException("Can only set the default display");
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized(mWindowMap) {
+ final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ if (displayContent != null) {
+ if (mode < 0 || mode > 1) {
+ mode = 0;
+ }
+ setForcedDisplayScalingModeLocked(displayContent, mode);
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DISPLAY_SCALING_FORCE, mode);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private void setForcedDisplayScalingModeLocked(DisplayContent displayContent,
+ int mode) {
+ Slog.i(TAG, "Using display scaling mode: " + (mode == 0 ? "auto" : "off"));
+
+ synchronized(displayContent.mDisplaySizeLock) {
+ displayContent.mDisplayScalingDisabled = (mode != 0);
+ }
+ reconfigureDisplayLocked(displayContent);
+ }
+
+ private void readForcedDisplayPropertiesLocked(final DisplayContent displayContent) {
+ // Display size.
String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.DISPLAY_SIZE_FORCED);
if (sizeStr == null || sizeStr.length() == 0) {
@@ -8414,6 +8441,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
+
+ // Display density.
String densityStr = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.DISPLAY_DENSITY_FORCED);
if (densityStr == null || densityStr.length() == 0) {
@@ -8432,6 +8461,16 @@ public class WindowManagerService extends IWindowManager.Stub
} catch (NumberFormatException ex) {
}
}
+
+ // Display scaling mode.
+ int mode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.DISPLAY_SCALING_FORCE, 0);
+ if (mode != 0) {
+ synchronized(displayContent.mDisplaySizeLock) {
+ Slog.i(TAG, "FORCED DISPLAY SCALING DISABLED");
+ displayContent.mDisplayScalingDisabled = true;
+ }
+ }
}
// displayContent must not be null
@@ -8564,17 +8603,17 @@ public class WindowManagerService extends IWindowManager.Stub
// displayContent must not be null
private void reconfigureDisplayLocked(DisplayContent displayContent) {
// TODO: Multidisplay: for now only use with default display.
+ if (!mDisplayReady) {
+ return;
+ }
configureDisplayPolicyLocked(displayContent);
displayContent.layoutNeeded = true;
boolean configChanged = updateOrientationFromAppTokensLocked(false);
mTempConfiguration.setToDefaults();
mTempConfiguration.fontScale = mCurConfiguration.fontScale;
- if (computeScreenConfigurationLocked(mTempConfiguration)) {
- if (mCurConfiguration.diff(mTempConfiguration) != 0) {
- configChanged = true;
- }
- }
+ computeScreenConfigurationLocked(mTempConfiguration);
+ configChanged |= mCurConfiguration.diff(mTempConfiguration) != 0;
if (configChanged) {
mWaitingForConfig = true;
@@ -8700,7 +8739,7 @@ public class WindowManagerService extends IWindowManager.Stub
numRemoved++;
continue;
} else if (lastBelow == i-1) {
- if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
+ if (w.mAttrs.type == TYPE_WALLPAPER) {
lastBelow = i;
}
}
@@ -8735,7 +8774,7 @@ public class WindowManagerService extends IWindowManager.Stub
final int numTokens = tokens.size();
for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
final AppWindowToken wtoken = tokens.get(tokenNdx);
- if (wtoken.mDeferRemoval) {
+ if (wtoken.mIsExiting) {
continue;
}
i = reAddAppWindowsLocked(displayContent, i, wtoken);
@@ -8745,6 +8784,7 @@ public class WindowManagerService extends IWindowManager.Stub
i -= lastBelow;
if (i != numRemoved) {
+ displayContent.layoutNeeded = true;
Slog.w(TAG, "On display=" + displayContent.getDisplayId() + " Rebuild removed " +
numRemoved + " windows but added " + i,
new RuntimeException("here").fillInStackTrace());
@@ -8765,6 +8805,7 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.w(TAG, "Final window list:");
dumpWindowsLocked();
}
+ Arrays.fill(mRebuildTmp, null);
}
private final void assignLayersLocked(WindowList windows) {
@@ -8873,29 +8914,24 @@ public class WindowManagerService extends IWindowManager.Stub
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
mInLayout = true;
- boolean recoveringMemory = false;
- try {
- if (mForceRemoves != null) {
- recoveringMemory = true;
- // Wait a little bit for things to settle down, and off we go.
- for (int i=0; i<mForceRemoves.size(); i++) {
- WindowState ws = mForceRemoves.get(i);
- Slog.i(TAG, "Force removing: " + ws);
- removeWindowInnerLocked(ws.mSession, ws);
- }
- mForceRemoves = null;
- Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
- Object tmp = new Object();
- synchronized (tmp) {
- try {
- tmp.wait(250);
- } catch (InterruptedException e) {
- }
+ boolean recoveringMemory = false;
+ if (!mForceRemoves.isEmpty()) {
+ recoveringMemory = true;
+ // Wait a little bit for things to settle down, and off we go.
+ while (!mForceRemoves.isEmpty()) {
+ WindowState ws = mForceRemoves.remove(0);
+ Slog.i(TAG, "Force removing: " + ws);
+ removeWindowInnerLocked(ws);
+ }
+ Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
+ Object tmp = new Object();
+ synchronized (tmp) {
+ try {
+ tmp.wait(250);
+ } catch (InterruptedException e) {
}
}
- } catch (RuntimeException e) {
- Slog.wtf(TAG, "Unhandled exception while force removing for memory", e);
}
try {
@@ -8953,8 +8989,6 @@ public class WindowManagerService extends IWindowManager.Stub
+ displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
}
- WindowStateAnimator universeBackground = null;
-
mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
if (isDefaultDisplay) {
// Not needed on non-default displays.
@@ -9012,8 +9046,7 @@ public class WindowManagerService extends IWindowManager.Stub
|| ((win.isConfigChanged() || win.setInsetsChanged()) &&
((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
(win.mHasSurface && win.mAppToken != null &&
- win.mAppToken.layoutConfigChanges)))
- || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
+ win.mAppToken.layoutConfigChanges)))) {
if (!win.mLayoutAttached) {
if (initial) {
//Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
@@ -9037,16 +9070,6 @@ public class WindowManagerService extends IWindowManager.Stub
if (topAttached < 0) topAttached = i;
}
}
- if (win.mViewVisibility == View.VISIBLE
- && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
- && universeBackground == null) {
- universeBackground = win.mWinAnimator;
- }
- }
-
- if (mAnimator.mUniverseBackground != universeBackground) {
- mFocusMayChange = true;
- mAnimator.mUniverseBackground = universeBackground;
}
boolean attachedBehindDream = false;
@@ -9150,6 +9173,7 @@ public class WindowManagerService extends IWindowManager.Stub
goodToGo = false;
}
}
+
if (goodToGo && isWallpaperVisible(mWallpaperTarget)) {
boolean wallpaperGoodToGo = true;
for (int curTokenIndex = mWallpaperTokens.size() - 1;
@@ -9190,7 +9214,6 @@ public class WindowManagerService extends IWindowManager.Stub
if (mSkipAppTransitionAnimation) {
transit = AppTransition.TRANSIT_UNSET;
}
- mAppTransition.goodToGo();
mStartingIconInTransition = false;
mSkipAppTransitionAnimation = false;
@@ -9343,6 +9366,7 @@ public class WindowManagerService extends IWindowManager.Stub
for (int j = 0; j < N; j++) {
appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
}
+ mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
}
}
@@ -9365,6 +9389,7 @@ public class WindowManagerService extends IWindowManager.Stub
appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
}
mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+ mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
if (animLp != null) {
int layer = -1;
@@ -9401,6 +9426,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) {
scheduleRemoveStartingWindowLocked(wtoken);
}
+ mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
if (animLp != null) {
int layer = -1;
@@ -9485,6 +9511,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
mAppTransition.postAnimationCallback();
mAppTransition.clear();
@@ -9518,6 +9545,12 @@ public class WindowManagerService extends IWindowManager.Stub
int changes = 0;
mAppTransition.setIdle();
+
+ if (mDeferredHideWallpaper != null) {
+ hideWallpapersLocked(mDeferredHideWallpaper);
+ mDeferredHideWallpaper = null;
+ }
+
// Restore window app tokens to the ActivityManager views
ArrayList<TaskStack> stacks = getDefaultDisplayContentLocked().getStacks();
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
@@ -9614,14 +9647,12 @@ public class WindowManagerService extends IWindowManager.Stub
/**
* Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
- *
- * @param w WindowState this method is applied to.
- * @param currentTime The time which animations use for calculating transitions.
+ * @param w WindowState this method is applied to.
* @param innerDw Width of app window.
* @param innerDh Height of app window.
*/
- private void handleNotObscuredLocked(final WindowState w, final long currentTime,
- final int innerDw, final int innerDh) {
+ private void handleNotObscuredLocked(final WindowState w,
+ final int innerDw, final int innerDh) {
final WindowManager.LayoutParams attrs = w.mAttrs;
final int attrFlags = attrs.flags;
final boolean canBeSeen = w.isDisplayedLw();
@@ -9740,8 +9771,6 @@ public class WindowManagerService extends IWindowManager.Stub
+ Debug.getCallers(3));
}
- final long currentTime = SystemClock.uptimeMillis();
-
int i;
boolean updateInputWindowsNeeded = false;
@@ -9832,8 +9861,7 @@ public class WindowManagerService extends IWindowManager.Stub
if ((displayContent.pendingLayoutChanges &
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
- (adjustWallpaperWindowsLocked() &
- ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
+ adjustWallpaperWindowsLocked()) {
assignLayersLocked(windows);
displayContent.layoutNeeded = true;
}
@@ -9864,9 +9892,6 @@ public class WindowManagerService extends IWindowManager.Stub
// it is animating.
displayContent.pendingLayoutChanges = 0;
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
- + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
-
if (isDefaultDisplay) {
mPolicy.beginPostLayoutPolicyLw(dw, dh);
for (i = windows.size() - 1; i >= 0; i--) {
@@ -9901,7 +9926,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Update effect.
w.mObscured = mInnerFields.mObscured;
if (!mInnerFields.mObscured) {
- handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
+ handleNotObscuredLocked(w, innerDw, innerDh);
}
if (stack != null && !stack.testDimmingTag()) {
@@ -9918,18 +9943,20 @@ public class WindowManagerService extends IWindowManager.Stub
final WindowStateAnimator winAnimator = w.mWinAnimator;
- // If the window has moved due to its containing
- // content frame changing, then we'd like to animate
- // it.
- if (w.mHasSurface && w.shouldAnimateMove()) {
- // Frame has moved, containing content frame
- // has also moved, and we're not currently animating...
- // let's do something.
- Animation a = AnimationUtils.loadAnimation(mContext,
- com.android.internal.R.anim.window_move_from_decor);
- winAnimator.setAnimation(a);
- winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
- winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+ // If the window has moved due to its containing content frame changing, then
+ // notify the listeners and optionally animate it.
+ if (w.hasMoved()) {
+ // Frame has moved, containing content frame has also moved, and we're not
+ // currently animating... let's do something.
+ final int left = w.mFrame.left;
+ final int top = w.mFrame.top;
+ if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
+ Animation a = AnimationUtils.loadAnimation(mContext,
+ com.android.internal.R.anim.window_move_from_decor);
+ winAnimator.setAnimation(a);
+ winAnimator.mAnimDw = w.mLastFrame.left - left;
+ winAnimator.mAnimDh = w.mLastFrame.top - top;
+ }
//TODO (multidisplay): Accessibility supported only for the default display.
if (mAccessibilityController != null
@@ -9938,7 +9965,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
try {
- w.mClient.moved(w.mFrame.left, w.mFrame.top);
+ w.mClient.moved(left, top);
} catch (RemoteException e) {
}
}
@@ -9950,7 +9977,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (w.mHasSurface && !w.isHiddenFromUserLocked()) {
// Take care of the window being ready to display.
final boolean committed =
- winAnimator.commitFinishDrawingLocked(currentTime);
+ winAnimator.commitFinishDrawingLocked();
if (isDefaultDisplay && committed) {
if (w.mAttrs.type == TYPE_DREAM) {
// HACK: When a dream is shown, it may at that
@@ -10075,7 +10102,7 @@ public class WindowManagerService extends IWindowManager.Stub
defaultDisplay.pendingLayoutChanges);
}
- if (!mAnimator.mAnimating && mAppTransition.isRunning()) {
+ if (!mAnimator.mAppWindowAnimating && mAppTransition.isRunning()) {
// We have finished the animation of an app transition. To do
// this, we have delayed a lot of operations like showing and
// hiding apps, moving apps in Z-order, etc. The app token list
@@ -10188,7 +10215,7 @@ public class WindowManagerService extends IWindowManager.Stub
for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
AppWindowToken token = exitingAppTokens.get(i);
if (!token.hasVisible && !mClosingApps.contains(token) &&
- (!token.mDeferRemoval || token.allAppWindows.isEmpty())) {
+ (!token.mIsExiting || token.allAppWindows.isEmpty())) {
// Make sure there is no animation running on this token,
// so any windows associated with it will be removed as
// soon as their animations are complete
@@ -10196,12 +10223,7 @@ public class WindowManagerService extends IWindowManager.Stub
token.mAppAnimator.animating = false;
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
"performLayout: App token exiting now removed" + token);
- removeAppFromTaskLocked(token);
- exitingAppTokens.remove(i);
- final Task task = mTaskIdToTask.get(token.groupId);
- if (task != null && task.mDeferRemoval && task.mAppTokens.isEmpty()) {
- removeTaskLocked(task);
- }
+ token.removeAppFromTaskLocked();
}
}
}
@@ -10287,7 +10309,7 @@ public class WindowManagerService extends IWindowManager.Stub
DisplayContentList displayList = new DisplayContentList();
for (i = 0; i < N; i++) {
WindowState w = mPendingRemoveTmp[i];
- removeWindowInnerLocked(w.mSession, w);
+ removeWindowInnerLocked(w);
final DisplayContent displayContent = w.getDisplayContent();
if (displayContent != null && !displayList.contains(displayContent)) {
displayList.add(displayContent);
@@ -10390,8 +10412,7 @@ public class WindowManagerService extends IWindowManager.Stub
void scheduleAnimationLocked() {
if (!mAnimationScheduled) {
mAnimationScheduled = true;
- mChoreographer.postCallback(
- Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
+ mChoreographer.postFrameCallback(mAnimator.mAnimationFrameCallback);
}
}
@@ -10464,10 +10485,6 @@ public class WindowManagerService extends IWindowManager.Stub
EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
winAnimator.mSession.mPid, operation);
- if (mForceRemoves == null) {
- mForceRemoves = new ArrayList<WindowState>();
- }
-
long callingIdentity = Binder.clearCallingIdentity();
try {
// There was some problem... first, do a sanity check of the
@@ -10627,11 +10644,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
private WindowState computeFocusedWindowLocked() {
- if (mAnimator.mUniverseBackground != null
- && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
- return mAnimator.mUniverseBackground.mWin;
- }
-
final int displayCount = mDisplayContents.size();
for (int i = 0; i < displayCount; i++) {
final DisplayContent displayContent = mDisplayContents.valueAt(i);
@@ -10654,6 +10666,10 @@ public class WindowManagerService extends IWindowManager.Stub
+ ", flags=" + win.mAttrs.flags
+ ", canReceive=" + win.canReceiveKeys());
+ if (!win.canReceiveKeys()) {
+ continue;
+ }
+
AppWindowToken wtoken = win.mAppToken;
// If this window's application has been removed, just skip it.
@@ -10663,10 +10679,6 @@ public class WindowManagerService extends IWindowManager.Stub
continue;
}
- if (!win.canReceiveKeys()) {
- continue;
- }
-
// Descend through all of the app tokens and find the first that either matches
// win.mAppToken (return win) or mFocusedApp (return null).
if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING &&
@@ -10822,15 +10834,13 @@ public class WindowManagerService extends IWindowManager.Stub
scheduleAnimationLocked();
} else {
screenRotationAnimation.kill();
- screenRotationAnimation = null;
- mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
+ mAnimator.setScreenRotationAnimationLocked(displayId, null);
updateRotation = true;
}
} else {
if (screenRotationAnimation != null) {
screenRotationAnimation.kill();
- screenRotationAnimation = null;
- mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
+ mAnimator.setScreenRotationAnimationLocked(displayId, null);
}
updateRotation = true;
}
@@ -11097,7 +11107,7 @@ public class WindowManagerService extends IWindowManager.Stub
void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
- if (mTokenMap.size() > 0) {
+ if (!mTokenMap.isEmpty()) {
pw.println(" All tokens:");
Iterator<WindowToken> it = mTokenMap.values().iterator();
while (it.hasNext()) {
@@ -11111,7 +11121,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
- if (mWallpaperTokens.size() > 0) {
+ if (!mWallpaperTokens.isEmpty()) {
pw.println();
pw.println(" Wallpaper tokens:");
for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
@@ -11126,7 +11136,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
- if (mFinishedStarting.size() > 0) {
+ if (!mFinishedStarting.isEmpty()) {
pw.println();
pw.println(" Finishing start of application tokens:");
for (int i=mFinishedStarting.size()-1; i>=0; i--) {
@@ -11141,7 +11151,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
- if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
+ if (!mOpeningApps.isEmpty() || !mClosingApps.isEmpty()) {
pw.println();
if (mOpeningApps.size() > 0) {
pw.print(" mOpeningApps="); pw.println(mOpeningApps);
@@ -11376,7 +11386,7 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
pw.println(" mLayoutToAnim:");
- mAppTransition.dump(pw);
+ mAppTransition.dump(pw, " ");
}
}
@@ -11932,5 +11942,12 @@ public class WindowManagerService extends IWindowManager.Stub
WindowManagerService.this.removeWindowToken(token);
}
}
+
+ @Override
+ public void registerAppTransitionListener(AppTransitionListener listener) {
+ synchronized (mWindowMap) {
+ mAppTransition.registerListenerLocked(listener);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d7b537f..ad25462 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -16,21 +16,21 @@
package com.android.server.wm;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION;
import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
-import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import android.app.AppOpsManager;
import android.os.Debug;
@@ -133,7 +133,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {
int mLayoutSeq = -1;
- Configuration mConfiguration = null;
+ private Configuration mConfiguration = Configuration.EMPTY;
+ private Configuration mOverrideConfig = Configuration.EMPTY;
// Sticky answer to isConfigChanged(), remains true until new Configuration is assigned.
// Used only on {@link #TYPE_KEYGUARD}.
private boolean mConfigHasChanged;
@@ -234,7 +235,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {
final Rect mParentFrame = new Rect();
- // The entire screen area of the device.
+ // The entire screen area of the {@link TaskStack} this window is in. Usually equal to the
+ // screen area of the device.
final Rect mDisplayFrame = new Rect();
// The region of the display frame that the display type supports displaying content on. This
@@ -344,10 +346,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
/** When true this window can be displayed on screens owther than mOwnerUid's */
private boolean mShowToOwnerOnly;
- /** When true this window is at the top of the screen and should be layed out to extend under
- * the status bar */
- boolean mUnderStatusBar = true;
-
/**
* Wake lock for drawing.
* Even though it's slightly more expensive to do so, we will use a separate wake lock
@@ -480,6 +478,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (mAppToken != null) {
final DisplayContent appDisplay = getDisplayContent();
mNotOnAppsDisplay = displayContent != appDisplay;
+
+ if (mAppToken.showForAllUsers) {
+ // Windows for apps that can show for all users should also show when the
+ // device is locked.
+ mAttrs.flags |= FLAG_SHOW_WHEN_LOCKED;
+ }
}
mWinAnimator = new WindowStateAnimator(this);
@@ -518,18 +522,25 @@ final class WindowState implements WindowManagerPolicy.WindowState {
public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf) {
mHaveFrame = true;
- TaskStack stack = mAppToken != null ? getStack() : null;
- if (stack != null && !stack.isFullscreen()) {
- getStackBounds(stack, mContainingFrame);
- if (mUnderStatusBar) {
- mContainingFrame.top = pf.top;
+ final TaskStack stack = mAppToken != null ? getStack() : null;
+ final boolean nonFullscreenStack = stack != null && !stack.isFullscreen();
+ if (nonFullscreenStack) {
+ stack.getBounds(mContainingFrame);
+ final WindowState imeWin = mService.mInputMethodWindow;
+ if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this
+ && mContainingFrame.bottom > cf.bottom) {
+ // IME is up and obscuring this window. Adjust the window position so it is visible.
+ mContainingFrame.top -= mContainingFrame.bottom - cf.bottom;
}
+ // Make sure the containing frame is within the content frame so we don't layout
+ // resized window under screen decorations.
+ mContainingFrame.intersect(cf);
+ mDisplayFrame.set(mContainingFrame);
} else {
mContainingFrame.set(pf);
+ mDisplayFrame.set(df);
}
- mDisplayFrame.set(df);
-
final int pw = mContainingFrame.width();
final int ph = mContainingFrame.height();
@@ -587,9 +598,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
final int fw = mFrame.width();
final int fh = mFrame.height();
- //System.out.println("In: w=" + w + " h=" + h + " container=" +
- // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
-
float x, y;
if (mEnforceSizeCompat) {
x = mAttrs.x * mGlobalScale;
@@ -599,14 +607,19 @@ final class WindowState implements WindowManagerPolicy.WindowState {
y = mAttrs.y;
}
+ if (nonFullscreenStack) {
+ // Make sure window fits in containing frame since it is in a non-fullscreen stack as
+ // required by {@link Gravity#apply} call.
+ w = Math.min(w, pw);
+ h = Math.min(h, ph);
+ }
+
Gravity.apply(mAttrs.gravity, w, h, mContainingFrame,
(int) (x + mAttrs.horizontalMargin * pw),
(int) (y + mAttrs.verticalMargin * ph), mFrame);
- //System.out.println("Out: " + mFrame);
-
- // Now make sure the window fits in the overall display.
- Gravity.applyDisplay(mAttrs.gravity, df, mFrame);
+ // Now make sure the window fits in the overall display frame.
+ Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame);
// Make sure the content and visible frames are inside of the
// final window frame.
@@ -804,14 +817,14 @@ final class WindowState implements WindowManagerPolicy.WindowState {
TaskStack getStack() {
AppWindowToken wtoken = mAppToken == null ? mService.mFocusedApp : mAppToken;
if (wtoken != null) {
- Task task = mService.mTaskIdToTask.get(wtoken.groupId);
+ Task task = wtoken.mTask;
if (task != null) {
if (task.mStack != null) {
return task.mStack;
}
Slog.e(TAG, "getStack: mStack null for task=" + task);
} else {
- Slog.e(TAG, "getStack: " + this + " couldn't find taskId=" + wtoken.groupId
+ Slog.e(TAG, "getStack: " + this + " couldn't find task for " + wtoken
+ " Callers=" + Debug.getCallers(4));
}
}
@@ -819,10 +832,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
void getStackBounds(Rect bounds) {
- getStackBounds(getStack(), bounds);
- }
-
- private void getStackBounds(TaskStack stack, Rect bounds) {
+ final TaskStack stack = getStack();
if (stack != null) {
stack.getBounds(bounds);
return;
@@ -1070,16 +1080,14 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
/**
- * Return whether this window is wanting to have a translation
- * animation applied to it for an in-progress move. (Only makes
+ * Return whether this window has moved. (Only makes
* sense to call from performLayoutAndPlaceSurfacesLockedInner().)
*/
- boolean shouldAnimateMove() {
- return mContentChanged && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay()
- && (mFrame.top != mLastFrame.top
+ boolean hasMoved() {
+ return mHasSurface && mContentChanged && !mExiting && !mWinAnimator.mLastHidden
+ && mService.okToDisplay() && (mFrame.top != mLastFrame.top
|| mFrame.left != mLastFrame.left)
- && (mAttrs.privateFlags&PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
- && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove());
+ && (mAttachedWindow == null || !mAttachedWindow.hasMoved());
}
boolean isFullscreen(int screenWidth, int screenHeight) {
@@ -1088,9 +1096,13 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
boolean isConfigChanged() {
- boolean configChanged = mConfiguration != mService.mCurConfiguration
- && (mConfiguration == null
- || (mConfiguration.diff(mService.mCurConfiguration) != 0));
+ final TaskStack stack = getStack();
+ final Configuration overrideConfig =
+ (stack != null) ? stack.mOverrideConfig : Configuration.EMPTY;
+ final Configuration serviceConfig = mService.mCurConfiguration;
+ boolean configChanged =
+ (mConfiguration != serviceConfig && mConfiguration.diff(serviceConfig) != 0)
+ || (mOverrideConfig != overrideConfig && !mOverrideConfig.equals(overrideConfig));
if ((mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
// Retain configuration changed status until resetConfiguration called.
@@ -1119,8 +1131,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
}
- void setConfiguration(final Configuration newConfig) {
+ private void setConfiguration(
+ final Configuration newConfig, final Configuration newOverrideConfig) {
mConfiguration = newConfig;
+ mOverrideConfig = newOverrideConfig;
mConfigHasChanged = false;
}
@@ -1152,10 +1166,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
WindowState win = mService.windowForClientLocked(mSession, mClient, false);
Slog.i(TAG, "WIN DEATH: " + win);
if (win != null) {
- mService.removeWindowLocked(mSession, win);
+ mService.removeWindowLocked(win);
} else if (mHasSurface) {
Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid.");
- mService.removeWindowLocked(mSession, WindowState.this);
+ mService.removeWindowLocked(WindowState.this);
}
}
} catch (IllegalArgumentException ex) {
@@ -1328,6 +1342,15 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return displayContent.isDefaultDisplay;
}
+ @Override
+ public boolean isDimming() {
+ TaskStack stack = getStack();
+ if (stack == null) {
+ return false;
+ }
+ return stack.isDimming(mWinAnimator);
+ }
+
public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) {
mShowToOwnerOnly = showToOwnerOnly;
}
@@ -1339,7 +1362,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
win = win.mAttachedWindow;
}
if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
- && win.mAppToken != null && win.mAppToken.showWhenLocked) {
+ && win.mAppToken != null && win.mAppToken.showForAllUsers) {
// Save some cycles by not calling getDisplayInfo unless it is an application
// window intended for all users.
final DisplayContent displayContent = win.getDisplayContent();
@@ -1423,12 +1446,15 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
+ ": " + mCompatFrame);
boolean configChanged = isConfigChanged();
+ final TaskStack stack = getStack();
+ final Configuration overrideConfig =
+ (stack != null) ? stack.mOverrideConfig : Configuration.EMPTY;
if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) {
Slog.i(TAG, "Sending new config to window " + this + ": "
- + mWinAnimator.mSurfaceW + "x" + mWinAnimator.mSurfaceH
- + " / " + mService.mCurConfiguration);
+ + mWinAnimator.mSurfaceW + "x" + mWinAnimator.mSurfaceH + " / config="
+ + mService.mCurConfiguration + " overrideConfig=" + overrideConfig);
}
- setConfiguration(mService.mCurConfiguration);
+ setConfiguration(mService.mCurConfiguration, overrideConfig);
if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING)
Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
@@ -1505,7 +1531,11 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
void dump(PrintWriter pw, String prefix, boolean dumpAll) {
+ final TaskStack stack = getStack();
pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());
+ if (stack != null) {
+ pw.print(" stackId="); pw.print(stack.mStackId);
+ }
pw.print(" mSession="); pw.print(mSession);
pw.print(" mClient="); pw.println(mClient.asBinder());
pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid);
@@ -1589,6 +1619,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.print(prefix); pw.print("touchable region="); pw.println(region);
}
pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
+ if (mOverrideConfig != Configuration.EMPTY) {
+ pw.print(prefix); pw.print("mOverrideConfig="); pw.println(mOverrideConfig);
+ }
}
pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
pw.print(" mShownFrame="); mShownFrame.printShortString(pw);
@@ -1599,6 +1632,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.println();
pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
+ if (mWinAnimator.mHasClipRect) {
+ pw.print(" mLastClipRect=");
+ mWinAnimator.mLastClipRect.printShortString(pw);
+ }
pw.println();
}
if (mEnforceSizeCompat) {
@@ -1669,7 +1706,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.println(mWallpaperDisplayOffsetY);
}
if (mDrawLock != null) {
- pw.println("mDrawLock=" + mDrawLock);
+ pw.print(prefix); pw.println("mDrawLock=" + mDrawLock);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 4cdfc41..d6726c1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -53,21 +53,16 @@ import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerPolicy;
import android.view.WindowManager.LayoutParams;
-import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
-import com.android.internal.R;
import com.android.server.wm.WindowManagerService.H;
import java.io.PrintWriter;
import java.util.ArrayList;
-class WinAnimatorList extends ArrayList<WindowStateAnimator> {
-}
-
/**
* Keep track of animations and surface operations for a single WindowState.
**/
@@ -85,10 +80,6 @@ class WindowStateAnimator {
final Context mContext;
final boolean mIsWallpaper;
- // If this is a universe background window, this is the transformation
- // it is applying to the rest of the universe.
- final Transformation mUniverseTransform = new Transformation();
-
// Currently running animation.
boolean mAnimating;
boolean mLocalAnimating;
@@ -189,7 +180,7 @@ class WindowStateAnimator {
int mAttrType;
- public WindowStateAnimator(final WindowState win) {
+ WindowStateAnimator(final WindowState win) {
final WindowManagerService service = win.mService;
mService = service;
@@ -247,9 +238,7 @@ class WindowStateAnimator {
boolean isAnimating() {
return mAnimation != null
|| (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null)
- || (mAppAnimator != null &&
- (mAppAnimator.animation != null
- || mAppAnimator.mAppToken.inPendingTransaction));
+ || (mAppAnimator != null && mAppAnimator.isAnimating());
}
/** Is the window animating the DummyAnimation? */
@@ -486,7 +475,7 @@ class WindowStateAnimator {
mService.mPendingRemove.add(mWin);
mWin.mRemoveOnExit = false;
}
- mAnimator.hideWallpapersLocked(mWin);
+ mService.hideWallpapersLocked(mWin);
}
void hide() {
@@ -527,7 +516,7 @@ class WindowStateAnimator {
}
// This must be called while inside a transaction.
- boolean commitFinishDrawingLocked(long currentTime) {
+ boolean commitFinishDrawingLocked() {
if (DEBUG_STARTING_WINDOW &&
mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
@@ -984,7 +973,7 @@ class WindowStateAnimator {
}
mSurfaceControl.destroy();
}
- mAnimator.hideWallpapersLocked(mWin);
+ mService.hideWallpapersLocked(mWin);
} catch (RuntimeException e) {
Slog.w(TAG, "Exception thrown when destroying Window " + this
+ " surface " + mSurfaceControl + " session " + mSession
@@ -1010,7 +999,7 @@ class WindowStateAnimator {
WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
}
mPendingDestroySurface.destroy();
- mAnimator.hideWallpapersLocked(mWin);
+ mService.hideWallpapersLocked(mWin);
}
} catch (RuntimeException e) {
Slog.w(TAG, "Exception thrown when destroying Window "
@@ -1096,9 +1085,6 @@ class WindowStateAnimator {
if (appTransformation != null) {
tmpMatrix.postConcat(appTransformation.getMatrix());
}
- if (mAnimator.mUniverseBackground != null) {
- tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
- }
if (screenAnimation) {
tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
}
@@ -1164,9 +1150,6 @@ class WindowStateAnimator {
mHasClipRect = true;
}
}
- if (mAnimator.mUniverseBackground != null) {
- mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
- }
if (screenAnimation) {
mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
}
@@ -1192,15 +1175,12 @@ class WindowStateAnimator {
TAG, "computeShownFrameLocked: " + this +
" not attached, mAlpha=" + mAlpha);
- final boolean applyUniverseTransformation = (mAnimator.mUniverseBackground != null
- && mWin.mAttrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
- && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer);
MagnificationSpec spec = null;
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
}
- if (applyUniverseTransformation || spec != null) {
+ if (spec != null) {
final Rect frame = mWin.mFrame;
final float tmpFloats[] = mService.mTmpFloats;
final Matrix tmpMatrix = mWin.mTmpMatrix;
@@ -1208,10 +1188,6 @@ class WindowStateAnimator {
tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
- if (applyUniverseTransformation) {
- tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
- }
-
if (spec != null && !spec.isNop()) {
tmpMatrix.postScale(spec.scale, spec.scale);
tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
@@ -1231,9 +1207,6 @@ class WindowStateAnimator {
mWin.mShownFrame.set(x, y, x + w, y + h);
mShownAlpha = mAlpha;
- if (applyUniverseTransformation) {
- mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
- }
} else {
mWin.mShownFrame.set(mWin.mFrame);
if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
@@ -1248,7 +1221,7 @@ class WindowStateAnimator {
}
}
- void applyDecorRect(final Rect decorRect) {
+ private void applyDecorRect(final Rect decorRect) {
final WindowState w = mWin;
final int width = w.mFrame.width();
final int height = w.mFrame.height();
@@ -1301,17 +1274,9 @@ class WindowStateAnimator {
displayInfo.logicalHeight - w.mCompatFrame.top);
} else if (w.mLayer >= mService.mSystemDecorLayer) {
// Above the decor layer is easy, just use the entire window.
- // Unless we have a universe background... in which case all the
- // windows need to be cropped by the screen, so they don't cover
- // the universe background.
- if (mAnimator.mUniverseBackground == null) {
- w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
- } else {
- applyDecorRect(mService.mScreenRect);
- }
- } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
- || w.mDecorFrame.isEmpty()) {
- // The universe background isn't cropped, nor windows without policy decor.
+ w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
+ } else if (w.mDecorFrame.isEmpty()) {
+ // Windows without policy decor aren't cropped.
w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
} else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.mAnimating) {
// If we're animating, the wallpaper crop should only be updated at the end of the
@@ -1436,6 +1401,9 @@ class WindowStateAnimator {
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
"SIZE " + width + "x" + height, null);
mSurfaceControl.setSize(width, height);
+ mSurfaceControl.setMatrix(
+ mDsDx * w.mHScale, mDtDx * w.mVScale,
+ mDsDy * w.mHScale, mDtDy * w.mVScale);
mAnimator.setPendingLayoutChanges(w.getDisplayId(),
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
@@ -1482,7 +1450,7 @@ class WindowStateAnimator {
hide();
} else if (w.mAttachedHidden || !w.isOnScreen()) {
hide();
- mAnimator.hideWallpapersLocked(w);
+ mService.hideWallpapersLocked(w);
// If we are waiting for this window to handle an
// orientation change, well, it is hidden, so
@@ -1654,13 +1622,8 @@ class WindowStateAnimator {
}
if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
- RuntimeException e = null;
- if (!WindowManagerService.HIDE_STACK_CRAWLS) {
- e = new RuntimeException();
- e.fillInStackTrace();
- }
Slog.v(TAG, "performShow on " + this
- + ": mDrawState=" + mDrawState + " readyForDisplay="
+ + ": mDrawState=" + drawStateToString() + " readyForDisplay="
+ mWin.isReadyForDisplayIgnoringKeyguard()
+ " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING)
+ " during animation: policyVis=" + mWin.mPolicyVisibility
@@ -1671,7 +1634,8 @@ class WindowStateAnimator {
+ (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
+ " animating=" + mAnimating
+ " tok animating="
- + (mAppAnimator != null ? mAppAnimator.animating : false), e);
+ + (mAppAnimator != null ? mAppAnimator.animating : false) + " Callers="
+ + Debug.getCallers(3));
}
if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
@@ -1932,11 +1896,6 @@ class WindowStateAnimator {
pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
}
- if (mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) {
- pw.print(prefix); pw.print("mUniverseTransform=");
- mUniverseTransform.printShortString(pw);
- pw.println();
- }
if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
pw.print(" mAlpha="); pw.print(mAlpha);
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 1a672e6..b303505 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -83,8 +83,9 @@ class WindowToken {
WindowState win = windows.get(winNdx);
if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) Slog.w(WindowManagerService.TAG,
"removeAllWindows: removing win=" + win);
- win.mService.removeWindowLocked(win.mSession, win);
+ win.mService.removeWindowLocked(win);
}
+ windows.clear();
}
void dump(PrintWriter pw, String prefix) {