* Retrieves the {@param outBounds} from the stack with id {@param stackId}.
*/
void getStackBounds(int stackId, Rect outBounds);
+
+ /**
+ * Overrides all currently playing app animations with {@param a}.
+ */
+ void overridePlayingAppAnimationsLw(Animation a);
}
public interface PointerEventListener {
* FLAG_SHOW_ON_LOCK_SCREEN.
*
* @param isOccluded Whether the Keyguard is occluded by another window.
+ * @param animate Whether to play an animation for the state change.
*/
- void setOccluded(boolean isOccluded);
+ void setOccluded(boolean isOccluded, boolean animate);
void addStateMonitorCallback(IKeyguardStateCallback callback);
void verifyUnlock(IKeyguardExitCallback callback);
<java-symbol type="anim" name="lock_screen_behind_enter_fade_in" />
<java-symbol type="anim" name="lock_screen_wallpaper_exit" />
<java-symbol type="anim" name="launch_task_behind_source" />
+ <java-symbol type="anim" name="wallpaper_open_exit" />
<java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
<java-symbol type="dimen" name="status_bar_icon_size" />
}
@Override // Binder interface
- public void setOccluded(boolean isOccluded) {
+ public void setOccluded(boolean isOccluded, boolean animate) {
Trace.beginSection("KeyguardService.mBinder#setOccluded");
checkPermission();
- mKeyguardViewMediator.setOccluded(isOccluded);
+ mKeyguardViewMediator.setOccluded(isOccluded, animate);
Trace.endSection();
}
/**
* Notify us when the keyguard is occluded by another window
*/
- public void setOccluded(boolean isOccluded) {
+ public void setOccluded(boolean isOccluded, boolean animate) {
Trace.beginSection("KeyguardViewMediator#setOccluded");
if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded);
mHandler.removeMessages(SET_OCCLUDED);
- Message msg = mHandler.obtainMessage(SET_OCCLUDED, (isOccluded ? 1 : 0), 0);
+ Message msg = mHandler.obtainMessage(SET_OCCLUDED, isOccluded ? 1 : 0, animate ? 1 : 0);
mHandler.sendMessage(msg);
Trace.endSection();
}
/**
* Handles SET_OCCLUDED message sent by setOccluded()
*/
- private void handleSetOccluded(boolean isOccluded) {
+ private void handleSetOccluded(boolean isOccluded, boolean animate) {
Trace.beginSection("KeyguardViewMediator#handleSetOccluded");
synchronized (KeyguardViewMediator.this) {
if (mHiding && isOccluded) {
if (mOccluded != isOccluded) {
mOccluded = isOccluded;
- mStatusBarKeyguardViewManager.setOccluded(isOccluded);
+ mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate);
updateActivityLockScreenState();
adjustStatusBarLocked();
}
break;
case SET_OCCLUDED:
Trace.beginSection("KeyguardViewMediator#handleMessage SET_OCCLUDED");
- handleSetOccluded(msg.arg1 != 0);
+ handleSetOccluded(msg.arg1 != 0, msg.arg2 != 0);
Trace.endSection();
break;
case KEYGUARD_TIMEOUT:
* Whether an instant expand request is currently pending and we are just waiting for layout.
*/
private boolean mInstantExpanding;
+ private boolean mAnimateAfterExpanding;
PanelBar mBar;
vel = 0;
}
mFlingAnimationUtils.apply(animator, mExpandedHeight, target, vel, getHeight());
- if (expandBecauseOfFalsing) {
+ if (vel == 0) {
animator.setDuration(350);
}
} else {
}
mInstantExpanding = true;
+ mAnimateAfterExpanding = animate;
mUpdateFlingOnLayout = false;
abortAnimations();
cancelPeek();
if (mStatusBar.getStatusBarWindow().getHeight()
!= mStatusBar.getStatusBarHeight()) {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
- if (animate) {
+ if (mAnimateAfterExpanding) {
notifyExpandingStarted();
fling(0, true /* expand */);
} else {
*/
private static final int REMOTE_INPUT_KEPT_ENTRY_AUTO_CANCEL_DELAY = 200;
+ /**
+ * Never let the alpha become zero for surfaces that draw with SRC - otherwise the RenderNode
+ * won't draw anything and uninitialized memory will show through
+ * if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
+ * libhwui.
+ */
+ private static final float SRC_MIN_ALPHA = 0.002f;
+
static {
boolean onlyCoreApps;
boolean freeformWindowManagement;
if (mBackdrop.getVisibility() != View.VISIBLE) {
mBackdrop.setVisibility(View.VISIBLE);
if (allowEnterAnimation) {
- mBackdrop.animate().alpha(1f).withEndAction(new Runnable() {
- @Override
- public void run() {
- mStatusBarWindowManager.setBackdropShowing(true);
- }
- });
+ mBackdrop.setAlpha(SRC_MIN_ALPHA);
+ mBackdrop.animate().alpha(1f);
} else {
mBackdrop.animate().cancel();
mBackdrop.setAlpha(1f);
- mStatusBarWindowManager.setBackdropShowing(true);
}
+ mStatusBarWindowManager.setBackdropShowing(true);
metaDataChanged = true;
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
} else {
mStatusBarWindowManager.setBackdropShowing(false);
mBackdrop.animate()
- // Never let the alpha become zero - otherwise the RenderNode
- // won't draw anything and uninitialized memory will show through
- // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
- // libhwui.
- .alpha(0.002f)
+ .alpha(SRC_MIN_ALPHA)
.setInterpolator(Interpolators.ACCELERATE_DECELERATE)
.setDuration(300)
.setStartDelay(0)
});
if (mKeyguardFadingAway) {
mBackdrop.animate()
-
// Make it disappear faster, as the focus should be on the activity
// behind.
.setDuration(mKeyguardFadingAwayDuration / 2)
}
/**
+ * Plays the animation when an activity that was occluding Keyguard goes away.
+ */
+ public void animateKeyguardUnoccluding() {
+ mScrimController.animateKeyguardUnoccluding(500);
+ mNotificationPanel.setExpandedFraction(0f);
+ animateExpandNotificationsPanel();
+ }
+
+ /**
* Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
* Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
* because the launched app crashed or something else went wrong.
}
}
+ public void animateKeyguardUnoccluding(long duration) {
+ mAnimateChange = false;
+ setScrimBehindColor(0f);
+ mAnimateChange = true;
+ scheduleUpdate();
+ mDurationOverride = duration;
+ }
+
public void animateGoingToFullShade(long delay, long duration) {
mDurationOverride = duration;
mAnimationDelay = delay;
return mStatusBarWindowManager.isShowingWallpaper();
}
- public void setOccluded(boolean occluded) {
+ public void setOccluded(boolean occluded, boolean animate) {
if (occluded && !mOccluded && mShowing) {
if (mPhoneStatusBar.isInLaunchTransition()) {
mOccluded = true;
}
}
mOccluded = occluded;
- mPhoneStatusBar.updateMediaMetaData(false, false);
+ mPhoneStatusBar.updateMediaMetaData(false, animate && !occluded);
mStatusBarWindowManager.setKeyguardOccluded(occluded);
reset();
+ if (animate && !occluded) {
+ mPhoneStatusBar.animateKeyguardUnoccluding();
+ }
}
public boolean isOccluded() {
boolean showing = mKeyguardDelegate.isShowing();
if (wasOccluded && !isOccluded && showing) {
mKeyguardOccluded = false;
- mKeyguardDelegate.setOccluded(false);
+ mKeyguardDelegate.setOccluded(false, true /* animate */);
mStatusBar.getAttrs().privateFlags |= PRIVATE_FLAG_KEYGUARD;
if (!mKeyguardDelegate.hasLockscreenWallpaper()) {
mStatusBar.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
}
+ Animation anim = AnimationUtils.loadAnimation(mContext,
+ com.android.internal.R.anim.wallpaper_open_exit);
+ mWindowManagerFuncs.overridePlayingAppAnimationsLw(anim);
return true;
} else if (!wasOccluded && isOccluded && showing) {
mKeyguardOccluded = true;
- mKeyguardDelegate.setOccluded(true);
+ mKeyguardDelegate.setOccluded(true, false /* animate */);
mStatusBar.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD;
mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER;
return true;
mKeyguardService.onBootCompleted();
}
if (mKeyguardState.occluded) {
- mKeyguardService.setOccluded(mKeyguardState.occluded);
+ mKeyguardService.setOccluded(mKeyguardState.occluded, false /* animate */);
}
}
}
}
- public void setOccluded(boolean isOccluded) {
+ public void setOccluded(boolean isOccluded, boolean animate) {
if (mKeyguardService != null) {
- if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ")");
- mKeyguardService.setOccluded(isOccluded);
+ if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate);
+ mKeyguardService.setOccluded(isOccluded, animate);
}
mKeyguardState.occluded = isOccluded;
}
}
@Override // Binder interface
- public void setOccluded(boolean isOccluded) {
+ public void setOccluded(boolean isOccluded, boolean animate) {
try {
- mService.setOccluded(isOccluded);
+ mService.setOccluded(isOccluded, animate);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.WINDOW_REPLACEMENT_TIMEOUT_DURATION;
import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
import com.android.server.input.InputApplicationHandle;
import com.android.server.wm.WindowManagerService.H;
import android.view.IApplicationToken;
import android.view.View;
import android.view.WindowManager;
+import android.view.animation.Animation;
import java.io.PrintWriter;
import java.util.ArrayDeque;
}
}
+ /**
+ * See {@link WindowManagerService#overridePlayingAppAnimationsLw}
+ */
+ void overridePlayingAppAnimations(Animation a) {
+ if (mAppAnimator.isAnimating()) {
+ final WindowState win = findMainWindow();
+ final int width = win.mContainingFrame.width();
+ final int height = win.mContainingFrame.height();
+ mAppAnimator.setAnimation(a, width, height, false, STACK_CLIP_NONE);
+ }
+ }
+
@Override
void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
+import android.view.animation.Animation;
import java.io.PrintWriter;
import java.util.ArrayList;
return touchedWin;
}
+
+ /**
+ * See {@link WindowManagerService#overridePlayingAppAnimationsLw}.
+ */
+ void overridePlayingAppAnimationsLw(Animation a) {
+ for (int i = mStacks.size() - 1; i >= 0; i--) {
+ mStacks.get(i).overridePlayingAppAnimations(a);
+ }
+ }
}
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.Surface;
+import android.view.animation.Animation;
import com.android.server.EventLogTags;
return mStack.getDisplayContent().getDisplayInfo();
}
+ /**
+ * See {@link WindowManagerService#overridePlayingAppAnimationsLw}
+ */
+ void overridePlayingAppAnimations(Animation a) {
+ for (int i = mAppTokens.size() - 1; i >= 0; i--) {
+ mAppTokens.get(i).overridePlayingAppAnimations(a);
+ }
+ }
+
@Override
public String toString() {
return "{taskId=" + mTaskId + " appTokens=" + mAppTokens + " mdr=" + mDeferRemoval + "}";
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;
+import android.view.animation.Animation;
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
public boolean getBoundsAnimating() {
return mBoundsAnimating;
}
+
+ /**
+ * See {@link WindowManagerService#overridePlayingAppAnimationsLw}
+ */
+ void overridePlayingAppAnimations(Animation a) {
+ for (int i = mTasks.size() - 1; i >= 0; --i) {
+ mTasks.get(i).overridePlayingAppAnimations(a);
+ }
+ }
}
}
// Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
- // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
+ // layer. For keyguard over wallpaper put the wallpaper under the lowest window that
+ // is currently on screen, i.e. not hidden by policy.
int insertionIndex = 0;
if (visible && wallpaperTarget != null) {
final int type = wallpaperTarget.mAttrs.type;
final int privateFlags = wallpaperTarget.mAttrs.privateFlags;
if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0
|| type == TYPE_KEYGUARD_SCRIM) {
- insertionIndex = windows.indexOf(wallpaperTarget);
+ insertionIndex = Math.min(windows.indexOf(wallpaperTarget),
+ findLowestWindowOnScreen(windows));
}
}
if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT
return changed;
}
+ /**
+ * @return The index in {@param windows} of the lowest window that is currently on screen and
+ * not hidden by the policy.
+ */
+ private int findLowestWindowOnScreen(WindowList windows) {
+ final int size = windows.size();
+ for (int index = 0; index < size; index++) {
+ final WindowState win = windows.get(index);
+ if (win.isOnScreen()) {
+ return index;
+ }
+ }
+ return Integer.MAX_VALUE;
+ }
+
boolean adjustWallpaperWindows() {
mService.mWindowPlacerLocked.mWallpaperMayChange = false;
boolean allowWhenLocked = false;
// Show IME over the keyguard if the target allows it
allowWhenLocked |= (win.mIsImWindow || imeTarget == win) && showImeOverKeyguard;
- // Show SHOW_WHEN_LOCKED windows that turn on the screen
- allowWhenLocked |= (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 && win.mTurnOnScreen;
+ // Show SHOW_WHEN_LOCKED windows
+ allowWhenLocked |= (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
if (appShowWhenLocked != null) {
allowWhenLocked |= appShowWhenLocked == win.mAppToken
- // Show all SHOW_WHEN_LOCKED windows if some apps are shown over lockscreen
- || (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
- // Show error dialogs over apps that dismiss keyguard.
+ // Show error dialogs over apps that are shown on lockscreen
|| (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0;
}
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
}
}
+ @Override
+ public void overridePlayingAppAnimationsLw(Animation a) {
+ getDefaultDisplayContentLocked().overridePlayingAppAnimationsLw(a);
+ }
+
/**
* Re-sizes a stack and its containing tasks.
* @param stackId Id of stack to resize.