Merge changes from topic 'keyguard_refactor'
* changes:
The big keyguard transition refactor (6/n)
The big keyguard transition refactor (5/n)
The big keyguard transition refactor (4/n)
The big keyguard transition refactor (3/n)
The big keyguard transition refactor (2/n)
The big keyguard transition refactor (1/n)
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 0ba937a..1ee31d8 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -17,6 +17,7 @@
package android.app;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.IIntentSender;
import android.content.Intent;
@@ -179,4 +180,13 @@
* (-1).
*/
public abstract int getUidProcessState(int uid);
+
+ /**
+ * Called when Keyguard flags might have changed.
+ *
+ * @param callback Callback to run after activity visibilities have been reevaluated. This can
+ * be used from window manager so that when the callback is called, it's
+ * guaranteed that all apps have their visibility updated accordingly.
+ */
+ public abstract void notifyKeyguardFlagsChanged(@Nullable Runnable callback);
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 623a11d..15f6361 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1555,8 +1555,7 @@
case SET_LOCK_SCREEN_SHOWN_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
final boolean showing = data.readInt() != 0;
- final boolean occluded = data.readInt() != 0;
- setLockScreenShown(showing, occluded);
+ setLockScreenShown(showing);
reply.writeNoException();
return true;
}
@@ -2337,13 +2336,6 @@
return true;
}
- case KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION: {
- data.enforceInterface(IActivityManager.descriptor);
- keyguardWaitingForActivityDrawn();
- reply.writeNoException();
- return true;
- }
-
case KEYGUARD_GOING_AWAY_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
keyguardGoingAway(data.readInt());
@@ -5035,13 +5027,12 @@
reply.recycle();
return pfd;
}
- public void setLockScreenShown(boolean showing, boolean occluded) throws RemoteException
+ public void setLockScreenShown(boolean showing) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(showing ? 1 : 0);
- data.writeInt(occluded ? 1 : 0);
mRemote.transact(SET_LOCK_SCREEN_SHOWN_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
@@ -6060,16 +6051,6 @@
reply.recycle();
}
- public void keyguardWaitingForActivityDrawn() throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- mRemote.transact(KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION, data, reply, 0);
- reply.readException();
- data.recycle();
- reply.recycle();
- }
-
public void keyguardGoingAway(int flags)
throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 7b25c76..0323651 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -357,8 +357,7 @@
public void killPackageDependents(final String packageName, int userId) throws RemoteException;
public void forceStopPackage(final String packageName, int userId) throws RemoteException;
- // Note: probably don't want to allow applications access to these.
- public void setLockScreenShown(boolean showing, boolean occluded) throws RemoteException;
+ public void setLockScreenShown(boolean showing) throws RemoteException;
public void unhandledBack() throws RemoteException;
public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException;
@@ -518,8 +517,6 @@
public void showBootMessage(CharSequence msg, boolean always) throws RemoteException;
- public void keyguardWaitingForActivityDrawn() throws RemoteException;
-
/**
* Notify the system that the keyguard is going away.
*
@@ -1017,7 +1014,6 @@
int NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+228;
int START_ACTIVITY_FROM_RECENTS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 229;
int NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+230;
- int KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+231;
int START_ACTIVITY_AS_CALLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+232;
int ADD_APP_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+233;
int GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+234;
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 986ff46..39d7883 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -213,16 +213,6 @@
void dismissKeyguard();
void keyguardGoingAway(int flags);
- /**
- * Called to tell WindowManager whether the keyguard is animating in. While this property
- * is true, WindowManager won't assume that the keyguard is opaque (eg. WindowAnimator won't
- * force-hide windows just because keyguard is visible and WallpaperController won't occlude
- * app windows with the system wallpaper.
- *
- * <p>Requires CONTROL_KEYGUARD permission</p>
- */
- void setKeyguardAnimatingIn(boolean animating);
-
// Requires INTERACT_ACROSS_USERS_FULL permission
void setSwitchingUser(boolean switching);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f14acaa..106b211 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -599,13 +599,6 @@
public static final int TYPE_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW+27;
/**
- * Window type: keyguard scrim window. Shows if keyguard needs to be restarted.
- * In multiuser systems shows on all users' windows.
- * @hide
- */
- public static final int TYPE_KEYGUARD_SCRIM = FIRST_SYSTEM_WINDOW+29;
-
- /**
* Window type: Window for Presentation on top of private
* virtual display.
*/
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 653e583..f61a637 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -99,19 +99,30 @@
/**
* Called when a pending app transition gets cancelled.
+ *
+ * @param transit transition type indicating what kind of transition got cancelled
*/
- public void onAppTransitionCancelledLocked() {}
+ public void onAppTransitionCancelledLocked(int transit) {}
/**
* Called when an app transition gets started
*
+ * @param transit transition type indicating what kind of transition gets run, must be one
+ * of AppTransition.TRANSIT_* values
* @param openToken the token for the opening app
* @param closeToken the token for the closing app
* @param openAnimation the animation for the opening app
* @param closeAnimation the animation for the closing app
+ *
+ * @return Return any bit set of {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_LAYOUT},
+ * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_CONFIG},
+ * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_WALLPAPER},
+ * or {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_ANIM}.
*/
- public void onAppTransitionStartingLocked(IBinder openToken, IBinder closeToken,
- Animation openAnimation, Animation closeAnimation) {}
+ public int onAppTransitionStartingLocked(int transit, IBinder openToken, IBinder closeToken,
+ Animation openAnimation, Animation closeAnimation) {
+ return 0;
+ }
/**
* Called when an app transition is finished running.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index a6be493..a8d70c4 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -136,10 +136,10 @@
throws RemoteException;
/**
- * @return true if windows with FLAG_DISMISS_KEYGUARD should be allowed to show even if
- * the keyguard is locked.
+ * Called when the Keyguard occluded state changed.
+ * @param occluded Whether Keyguard is currently occluded or not.
*/
- boolean canShowDismissingWindowWhileLockedLw();
+ void onKeyguardOccludedChangedLw(boolean occluded);
/**
* Interface to the Window Manager state associated with a particular
@@ -424,6 +424,10 @@
public boolean isInMultiWindowMode();
public int getRotationAnimationHint();
+
+ public boolean isInputMethodWindow();
+
+ public int getDisplayId();
}
/**
@@ -509,9 +513,9 @@
void getStackBounds(int stackId, Rect outBounds);
/**
- * Overrides all currently playing app animations with {@param a}.
+ * Notifies window manager that {@link #isShowingDreamLw} has changed.
*/
- void overridePlayingAppAnimationsLw(Animation a);
+ void notifyShowingDreamChanged();
}
public interface PointerEventListener {
@@ -699,31 +703,15 @@
int uiMode);
/**
- * Return whether the given window is forcibly hiding all windows except windows with
- * FLAG_SHOW_WHEN_LOCKED set. Typically returns true for the keyguard.
- */
- public boolean isForceHiding(WindowManager.LayoutParams attrs);
-
-
- /**
- * Return whether the given window can become one that passes isForceHiding() test.
- * Typically returns true for the StatusBar.
+ * Return whether the given window can become the Keyguard window. Typically returns true for
+ * the StatusBar.
*/
public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs);
/**
- * Determine if a window that is behind one that is force hiding
- * (as determined by {@link #isForceHiding}) should actually be hidden.
- * For example, typically returns false for the status bar. Be careful
- * to return false for any window that you may hide yourself, since this
- * will conflict with what you set.
+ * @return whether {@param win} can be hidden by Keyguard
*/
- public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs);
-
- /**
- * Return the window that is hiding the keyguard, if such a thing exists.
- */
- public WindowState getWinShowWhenLockedLw();
+ public boolean canBeHiddenByKeyguardLw(WindowState win);
/**
* Called when the system would like to show a UI to indicate that an
@@ -834,16 +822,16 @@
boolean forceDefault);
/**
- * Create and return an animation to re-display a force hidden window.
+ * Create and return an animation to re-display a window that was force hidden by Keyguard.
*/
- public Animation createForceHideEnterAnimation(boolean onWallpaper,
+ public Animation createHiddenByKeyguardExit(boolean onWallpaper,
boolean goingToNotificationShade);
/**
- * Create and return an animation to let the wallpaper disappear after being shown on a force
- * hiding window.
+ * Create and return an animation to let the wallpaper disappear after being shown behind
+ * Keyguard.
*/
- public Animation createForceHideWallpaperExitAnimation(boolean goingToNotificationShade);
+ public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade);
/**
* Called from the input reader thread before a key is enqueued.
@@ -1000,7 +988,7 @@
* @param attached For sub-windows, the window it is attached to. Otherwise null.
*/
public void applyPostLayoutPolicyLw(WindowState win,
- WindowManager.LayoutParams attrs, WindowState attached);
+ WindowManager.LayoutParams attrs, WindowState attached, WindowState imeTarget);
/**
* Called following layout of all windows and after policy has been applied
@@ -1147,11 +1135,11 @@
public boolean isKeyguardSecure(int userId);
/**
- * Return whether the keyguard is on.
+ * Return whether the keyguard is currently occluded.
*
- * @return true if in keyguard is on.
+ * @return true if in keyguard is occluded, false otherwise
*/
- public boolean isKeyguardShowingOrOccluded();
+ public boolean isKeyguardOccluded();
/**
* @return true if in keyguard is on and not occluded.
@@ -1159,6 +1147,11 @@
public boolean isKeyguardShowingAndNotOccluded();
/**
+ * @return whether Keyguard is in trusted state and can be dismissed without credentials
+ */
+ public boolean isKeyguardTrustedLw();
+
+ /**
* inKeyguardRestrictedKeyInputMode
*
* if keyguard screen is showing or in restricted key input mode (i.e. in
@@ -1175,11 +1168,6 @@
public void dismissKeyguardLw();
/**
- * Notifies the keyguard that the activity has drawn it was waiting for.
- */
- public void notifyActivityDrawnForKeyguardLw();
-
- /**
* Ask the policy whether the Keyguard has drawn. If the Keyguard is disabled, this method
* returns true as soon as we know that Keyguard is disabled.
*
@@ -1187,6 +1175,8 @@
*/
public boolean isKeyguardDrawnLw();
+ public boolean isShowingDreamLw();
+
/**
* Given an orientation constant, returns the appropriate surface rotation,
* taking into account sensors, docking mode, rotation lock, and other factors.
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index 50dd33a..788103d 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -34,7 +34,6 @@
void addStateMonitorCallback(IKeyguardStateCallback callback);
void verifyUnlock(IKeyguardExitCallback callback);
- void keyguardDone(boolean authenticated, boolean wakeup);
void dismiss(boolean allowWhileOccluded);
void onDreamingStarted();
void onDreamingStopped();
@@ -93,10 +92,4 @@
* @param fadeoutDuration the duration of the exit animation, in milliseconds
*/
void startKeyguardExitAnimation(long startTime, long fadeoutDuration);
-
- /**
- * Notifies the Keyguard that the activity that was starting has now been drawn and it's safe
- * to start the keyguard dismiss sequence.
- */
- void onActivityDrawn();
}
diff --git a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
index 474ffea..327d218 100644
--- a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
@@ -76,12 +76,6 @@
void playTrustedSound();
/**
- * @return true if and only if Keyguard is showing or if Keyguard is disabled by an external app
- * (legacy API)
- */
- boolean isInputRestricted();
-
- /**
* @return true if the screen is on
*/
boolean isScreenOn();
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainer.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainer.java
index a616369..4947863 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainer.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainer.java
@@ -31,7 +31,7 @@
// This should be incremented any time this class or ActivityStarter or BaseStatusBarHeader
// change in incompatible ways.
- public static final int VERSION = 2;
+ public static final int VERSION = 3;
public QSContainer(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -116,7 +116,6 @@
void startPendingIntentDismissingKeyguard(PendingIntent intent);
void startActivity(Intent intent, boolean dismissShade);
void startActivity(Intent intent, boolean dismissShade, Callback callback);
- void preventNextAnimation();
interface Callback {
void onActivityStarted(int resultCode);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index e05e507..816d70d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -81,15 +81,6 @@
}
@Override // Binder interface
- public void keyguardDone(boolean authenticated, boolean wakeup) {
- Trace.beginSection("KeyguardService.mBinder#keyguardDone");
- checkPermission();
- // TODO: Remove wakeup
- mKeyguardViewMediator.keyguardDone(authenticated);
- Trace.endSection();
- }
-
- @Override // Binder interface
public void setOccluded(boolean isOccluded, boolean animate) {
Trace.beginSection("KeyguardService.mBinder#setOccluded");
checkPermission();
@@ -202,12 +193,6 @@
mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration);
Trace.endSection();
}
-
- @Override
- public void onActivityDrawn() {
- checkPermission();
- mKeyguardViewMediator.onActivityDrawn();
- }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 24247e4..9ae341a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -135,7 +135,6 @@
private static final boolean DEBUG = KeyguardConstants.DEBUG;
private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
- private final static boolean DBG_WAKE = false;
private final static String TAG = "KeyguardViewMediator";
@@ -145,25 +144,23 @@
"com.android.internal.policy.impl.PhoneWindowManager.DELAYED_LOCK";
// used for handler messages
- private static final int SHOW = 2;
- private static final int HIDE = 3;
- private static final int RESET = 4;
- private static final int VERIFY_UNLOCK = 5;
- private static final int NOTIFY_FINISHED_GOING_TO_SLEEP = 6;
- private static final int NOTIFY_SCREEN_TURNING_ON = 7;
- private static final int KEYGUARD_DONE = 9;
- private static final int KEYGUARD_DONE_DRAWING = 10;
- private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
- private static final int SET_OCCLUDED = 12;
- private static final int KEYGUARD_TIMEOUT = 13;
- private static final int DISMISS = 17;
- private static final int START_KEYGUARD_EXIT_ANIM = 18;
- private static final int ON_ACTIVITY_DRAWN = 19;
- private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 20;
- private static final int NOTIFY_STARTED_WAKING_UP = 21;
- private static final int NOTIFY_SCREEN_TURNED_ON = 22;
- private static final int NOTIFY_SCREEN_TURNED_OFF = 23;
- private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 24;
+ private static final int SHOW = 1;
+ private static final int HIDE = 2;
+ private static final int RESET = 3;
+ private static final int VERIFY_UNLOCK = 4;
+ private static final int NOTIFY_FINISHED_GOING_TO_SLEEP = 5;
+ private static final int NOTIFY_SCREEN_TURNING_ON = 6;
+ private static final int KEYGUARD_DONE = 7;
+ private static final int KEYGUARD_DONE_DRAWING = 8;
+ private static final int SET_OCCLUDED = 9;
+ private static final int KEYGUARD_TIMEOUT = 10;
+ private static final int DISMISS = 11;
+ private static final int START_KEYGUARD_EXIT_ANIM = 12;
+ private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 13;
+ private static final int NOTIFY_STARTED_WAKING_UP = 14;
+ private static final int NOTIFY_SCREEN_TURNED_ON = 15;
+ private static final int NOTIFY_SCREEN_TURNED_OFF = 16;
+ private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 17;
/**
* The default amount of time we stay awake (used for all key input)
@@ -185,11 +182,6 @@
private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000;
/**
- * Secure setting whether analytics are collected on the keyguard.
- */
- private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";
-
- /**
* Boolean option for doKeyguardLocked/doKeyguardTimeout which, when set to true, forces the
* keyguard to show even if it is disabled for the current user.
*/
@@ -209,16 +201,9 @@
/** High level access to the power manager for WakeLocks */
private PowerManager mPM;
- /** High level access to the window manager for dismissing keyguard animation */
- private IWindowManager mWM;
-
-
/** TrustManager for letting it know when we change visibility */
private TrustManager mTrustManager;
- /** SearchManager for determining whether or not search assistant is available */
- private SearchManager mSearchManager;
-
/**
* Used to keep the device awake while to ensure the keyguard finishes opening before
* we sleep.
@@ -342,8 +327,6 @@
private boolean mWakeAndUnlocking;
private IKeyguardDrawnCallback mDrawnCallback;
- private boolean mIsPerUserLock;
-
KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@Override
@@ -533,7 +516,7 @@
}
if (!mKeyguardDonePending) {
- KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
+ KeyguardViewMediator.this.handleKeyguardDone(true /* authenticated */);
}
if (strongAuth) {
mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
@@ -584,7 +567,7 @@
if (mKeyguardDonePending) {
// Somebody has called keyguardDonePending before, which means that we are
// authenticated
- KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
+ KeyguardViewMediator.this.handleKeyguardDone(true /* authenticated */);
}
Trace.endSection();
}
@@ -600,11 +583,6 @@
}
@Override
- public boolean isInputRestricted() {
- return KeyguardViewMediator.this.isInputRestricted();
- }
-
- @Override
public boolean isScreenOn() {
return mDeviceInteractive;
}
@@ -645,7 +623,6 @@
private void setupLocked() {
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mWM = WindowManagerGlobal.getWindowManagerService();
mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
@@ -720,14 +697,12 @@
* Let us know that the system is ready after startup.
*/
public void onSystemReady() {
- mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
synchronized (this) {
if (DEBUG) Log.d(TAG, "onSystemReady");
mSystemReady = true;
doKeyguardLocked(null);
mUpdateMonitor.registerCallback(mUpdateCallback);
}
- mIsPerUserLock = StorageManager.isFileEncryptedNativeOrEmulated();
// Most services aren't available until the system reaches the ready state, so we
// send it here when the device first boots.
maybeSendUserPresentBroadcast();
@@ -1153,7 +1128,6 @@
if (mOccluded != isOccluded) {
mOccluded = isOccluded;
mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate);
- updateActivityLockScreenState();
adjustStatusBarLocked();
}
}
@@ -1514,9 +1488,6 @@
Trace.beginSection("KeyguardViewMediator#handleMessage KEYGUARD_DONE_PENDING_TIMEOUT");
Log.w(TAG, "Timeout while waiting for activity drawn!");
Trace.endSection();
- // Fall through.
- case ON_ACTIVITY_DRAWN:
- handleOnActivityDrawn();
break;
}
}
@@ -1638,7 +1609,7 @@
private void updateActivityLockScreenState() {
Trace.beginSection("KeyguardViewMediator#updateActivityLockScreenState");
try {
- ActivityManagerNative.getDefault().setLockScreenShown(mShowing, mOccluded);
+ ActivityManagerNative.getDefault().setLockScreenShown(mShowing);
} catch (RemoteException e) {
}
Trace.endSection();
@@ -1668,7 +1639,6 @@
mWakeAndUnlocking = false;
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
- updateActivityLockScreenState();
adjustStatusBarLocked();
userActivity();
@@ -1745,13 +1715,6 @@
Trace.endSection();
}
- private void handleOnActivityDrawn() {
- if (DEBUG) Log.d(TAG, "handleOnActivityDrawn: mKeyguardDonePending=" + mKeyguardDonePending);
- if (mKeyguardDonePending) {
- mStatusBarKeyguardViewManager.onActivityDrawn();
- }
- }
-
private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) {
Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation");
if (DEBUG) Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
@@ -1784,7 +1747,6 @@
mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
- updateActivityLockScreenState();
adjustStatusBarLocked();
sendUserPresentBroadcast();
}
@@ -1831,7 +1793,7 @@
private void handleReset() {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleReset");
- mStatusBarKeyguardViewManager.reset();
+ mStatusBarKeyguardViewManager.reset(true /* hideBouncerWhenShowing */);
}
}
@@ -1845,7 +1807,6 @@
if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
setShowingLocked(true);
mStatusBarKeyguardViewManager.verifyUnlock();
- updateActivityLockScreenState();
}
Trace.endSection();
}
@@ -1964,10 +1925,6 @@
Trace.endSection();
}
- public void onActivityDrawn() {
- mHandler.sendEmptyMessage(ON_ACTIVITY_DRAWN);
- }
-
public ViewMediatorCallback getViewMediatorCallback() {
return mViewMediatorCallback;
}
@@ -2027,6 +1984,7 @@
}
updateInputRestrictedLocked();
mTrustManager.reportKeyguardShowingChanged();
+ updateActivityLockScreenState();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 76440d5..70e21d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -345,17 +345,12 @@
dismissKeyguardThenExecute(new OnDismissAction() {
@Override
public boolean onDismiss() {
- if (keyguardShowing && !afterKeyguardGone) {
- try {
- ActivityManagerNative.getDefault()
- .keyguardWaitingForActivityDrawn();
- ActivityManagerNative.getDefault().resumeAppSwitches();
- } catch (RemoteException e) {
- }
+ try {
+ ActivityManagerNative.getDefault().resumeAppSwitches();
+ } catch (RemoteException e) {
}
boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
- overrideActivityPendingAppTransition(keyguardShowing && !afterKeyguardGone);
// close the shade if it was open
if (handled) {
@@ -1052,24 +1047,15 @@
}
private void startNotificationGutsIntent(final Intent intent, final int appUid) {
- final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
dismissKeyguardThenExecute(new OnDismissAction() {
@Override
public boolean onDismiss() {
AsyncTask.execute(new Runnable() {
public void run() {
- try {
- if (keyguardShowing) {
- ActivityManagerNative.getDefault()
- .keyguardWaitingForActivityDrawn();
- }
- TaskStackBuilder.create(mContext)
- .addNextIntentWithParentStack(intent)
- .startActivities(getActivityOptions(),
- new UserHandle(UserHandle.getUserId(appUid)));
- overrideActivityPendingAppTransition(keyguardShowing);
- } catch (RemoteException e) {
- }
+ TaskStackBuilder.create(mContext)
+ .addNextIntentWithParentStack(intent)
+ .startActivities(getActivityOptions(),
+ new UserHandle(UserHandle.getUserId(appUid)));
}
});
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
@@ -1832,11 +1818,6 @@
@Override
public void run() {
try {
- if (keyguardShowing && !afterKeyguardGone) {
- ActivityManagerNative.getDefault()
- .keyguardWaitingForActivityDrawn();
- }
-
// The intent we are sending is for the application, which
// won't have permission to immediately start an activity after
// the user switches to home. We know it is safe to do at this
@@ -1855,8 +1836,6 @@
}
if (intent.isActivity()) {
mAssistManager.hideAssist();
- overrideActivityPendingAppTransition(keyguardShowing
- && !afterKeyguardGone);
}
}
}.start();
@@ -1943,11 +1922,6 @@
@Override
public void run() {
try {
- if (keyguardShowing && !afterKeyguardGone) {
- ActivityManagerNative.getDefault()
- .keyguardWaitingForActivityDrawn();
- }
-
// The intent we are sending is for the application, which
// won't have permission to immediately start an activity after
// the user switches to home. We know it is safe to do at this
@@ -1993,8 +1967,6 @@
}
if (intent.isActivity()) {
mAssistManager.hideAssist();
- overrideActivityPendingAppTransition(keyguardShowing
- && !afterKeyguardGone);
}
}
@@ -2065,16 +2037,6 @@
public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
}
- public void overrideActivityPendingAppTransition(boolean keyguardShowing) {
- if (keyguardShowing) {
- try {
- mWindowManagerService.overridePendingAppTransition(null, 0, 0, null);
- } catch (RemoteException e) {
- Log.w(TAG, "Error overriding app transition: " + e);
- }
- }
- }
-
protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender,
String notificationKey) {
final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index f9b7bb5..dfb06d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -496,7 +496,6 @@
} catch (RemoteException e) {
Log.w(TAG, "Unable to start camera activity", e);
}
- mActivityStarter.preventNextAnimation();
final boolean launched = isSuccessfulLaunch(result);
post(new Runnable() {
@Override
@@ -539,7 +538,6 @@
@Override
public void run() {
mAssistManager.launchVoiceAssistFromKeyguard();
- mActivityStarter.preventNextAnimation();
}
};
if (mPhoneStatusBar.isKeyguardCurrentlySecure()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 7b35cbd..cda0bfe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1858,6 +1858,7 @@
mLaunchAnimationEndRunnable.run();
mLaunchAnimationEndRunnable = null;
}
+ mStatusBar.readyForKeyguardDone();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index be03ce6..669a512 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -37,7 +37,6 @@
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.IActivityManager;
-import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -51,7 +50,6 @@
import android.content.IntentSender;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -2515,11 +2513,6 @@
startActivityDismissingKeyguard(intent, false, dismissShade, callback);
}
- @Override
- public void preventNextAnimation() {
- overrideActivityPendingAppTransition(true /* keyguardShowing */);
- }
-
public void setQsExpanded(boolean expanded) {
mStatusBarWindowManager.setQsExpanded(expanded);
mKeyguardStatusView.setImportantForAccessibility(expanded
@@ -2871,7 +2864,7 @@
for (int i = 0; i < size; i++) {
clonedList.get(i).run();
}
-
+ mStatusBarKeyguardViewManager.readyForKeyguardDone();
}
@Override
@@ -3498,7 +3491,6 @@
final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
mContext, intent, mCurrentUserId);
- final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Runnable runnable = new Runnable() {
@Override
public void run() {
@@ -3529,8 +3521,6 @@
} catch (RemoteException e) {
Log.w(TAG, "Unable to start activity", e);
}
- overrideActivityPendingAppTransition(
- keyguardShowing && !afterKeyguardGone);
if (callback != null) {
callback.onActivityStarted(result);
}
@@ -3548,36 +3538,24 @@
afterKeyguardGone, true /* deferred */);
}
+ public void readyForKeyguardDone() {
+ mStatusBarKeyguardViewManager.readyForKeyguardDone();
+ }
+
public void executeRunnableDismissingKeyguard(final Runnable runnable,
final Runnable cancelAction,
final boolean dismissShade,
final boolean afterKeyguardGone,
final boolean deferred) {
- final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
- dismissKeyguardThenExecute(new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- AsyncTask.execute(new Runnable() {
- @Override
- public void run() {
- try {
- if (keyguardShowing && !afterKeyguardGone) {
- ActivityManagerNative.getDefault()
- .keyguardWaitingForActivityDrawn();
- }
- if (runnable != null) {
- runnable.run();
- }
- } catch (RemoteException e) {
- }
- }
- });
- if (dismissShade) {
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
- true /* delayed*/);
- }
- return deferred;
+ dismissKeyguardThenExecute(() -> {
+ if (runnable != null) {
+ AsyncTask.execute(runnable);
}
+ if (dismissShade) {
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
+ true /* delayed*/);
+ }
+ return deferred;
}, cancelAction, afterKeyguardGone);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 77c60fb..d296498 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -120,14 +120,14 @@
mShowing = true;
mStatusBarWindowManager.setKeyguardShowing(true);
mScrimController.abortKeyguardFadingOut();
- reset();
+ reset(true /* hideBouncerWhenShowing */);
}
/**
* Shows the notification keyguard or the bouncer depending on
* {@link KeyguardBouncer#needsFullscreenBouncer()}.
*/
- protected void showBouncerOrKeyguard() {
+ protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
if (mBouncer.needsFullscreenBouncer()) {
// The keyguard might be showing (already). So we need to hide it.
@@ -135,8 +135,10 @@
mBouncer.show(true /* resetSecuritySelection */);
} else {
mPhoneStatusBar.showKeyguard();
- mBouncer.hide(false /* destroyView */);
- mBouncer.prepare();
+ if (hideBouncerWhenShowing) {
+ mBouncer.hide(false /* destroyView */);
+ mBouncer.prepare();
+ }
}
}
@@ -163,14 +165,14 @@
/**
* Reset the state of the view.
*/
- public void reset() {
+ public void reset(boolean hideBouncerWhenShowing) {
if (mShowing) {
if (mOccluded) {
mPhoneStatusBar.hideKeyguard();
mPhoneStatusBar.stopWaitingForKeyguardExit();
mBouncer.hide(false /* destroyView */);
} else {
- showBouncerOrKeyguard();
+ showBouncerOrKeyguard(hideBouncerWhenShowing);
}
KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset();
updateStates();
@@ -257,7 +259,7 @@
@Override
public void run() {
mStatusBarWindowManager.setKeyguardOccluded(mOccluded);
- reset();
+ reset(true /* hideBouncerWhenShowing */);
}
});
return;
@@ -268,7 +270,10 @@
mPhoneStatusBar.updateMediaMetaData(false, animate && !occluded);
}
mStatusBarWindowManager.setKeyguardOccluded(occluded);
- reset();
+
+ // If Keyguard is reshown, don't hide the bouncer as it might just have been requested by
+ // a FLAG_DISMISS_KEYGUARD_ACTIVITY.
+ reset(false /* hideBouncerWhenShowing*/);
if (animate && !occluded && mShowing) {
mPhoneStatusBar.animateKeyguardUnoccluding();
}
@@ -418,9 +423,7 @@
* Dismisses the keyguard by going to the next screen or making it gone.
*/
public void dismiss() {
- if (mDeviceInteractive || mDeviceWillWakeUp) {
- showBouncer();
- }
+ showBouncer();
}
/**
@@ -445,7 +448,7 @@
public boolean onBackPressed() {
if (mBouncer.isShowing()) {
mPhoneStatusBar.endAffordanceLaunch();
- reset();
+ reset(true /* hideBouncerWhenShowing */);
return true;
}
return false;
@@ -556,17 +559,8 @@
return mBouncer.interceptMediaKey(event);
}
- public void onActivityDrawn() {
- if (mPhoneStatusBar.isCollapsing()) {
- mPhoneStatusBar.addPostCollapseAction(new Runnable() {
- @Override
- public void run() {
- mViewMediatorCallback.readyForKeyguardDone();
- }
- });
- } else {
- mViewMediatorCallback.readyForKeyguardDone();
- }
+ public void readyForKeyguardDone() {
+ mViewMediatorCallback.readyForKeyguardDone();
}
public boolean shouldDisableWindowAnimationsForUnlock() {
@@ -581,10 +575,6 @@
return mBouncer.isSecure() || mLockPatternUtils.isSecure(userId);
}
- public boolean isInputRestricted() {
- return mViewMediatorCallback.isInputRestricted();
- }
-
public void keyguardGoingAway() {
mPhoneStatusBar.keyguardGoingAway();
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 40f0aae..5d41d36 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import android.app.ApplicationThreadConstants;
+import android.annotation.Nullable;
import android.os.IDeviceIdentifiersPolicyService;
import android.util.Size;
import android.util.TypedValue;
@@ -312,7 +313,6 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
@@ -374,13 +374,14 @@
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
+import static com.android.server.wm.AppTransition.TRANSIT_NONE;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
-public final class ActivityManagerService extends ActivityManagerNative
+public class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
@@ -549,6 +550,7 @@
/** Run all ActivityStacks through this */
final ActivityStackSupervisor mStackSupervisor;
+ private final KeyguardController mKeyguardController;
final ActivityStarter mActivityStarter;
@@ -632,7 +634,7 @@
public boolean canShowErrorDialogs() {
return mShowDialogs && !mSleeping && !mShuttingDown
- && mLockScreenShown != LOCK_SCREEN_SHOWN;
+ && !mKeyguardController.isKeyguardShowing();
}
private static final class PriorityState {
@@ -1251,14 +1253,6 @@
*/
final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
- static final int LOCK_SCREEN_HIDDEN = 0;
- static final int LOCK_SCREEN_LEAVING = 1;
- static final int LOCK_SCREEN_SHOWN = 2;
- /**
- * State of external call telling us if the lock screen is shown.
- */
- int mLockScreenShown = LOCK_SCREEN_HIDDEN;
-
/**
* Set if we are shutting down the system, similar to sleeping.
*/
@@ -2621,6 +2615,7 @@
mStackSupervisor = new ActivityStackSupervisor(this);
mStackSupervisor.onConfigurationChanged(mTempConfig);
+ mKeyguardController = mStackSupervisor.mKeyguardController;
mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
mTaskChangeNotificationController =
@@ -3037,7 +3032,7 @@
mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
}
- private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
+ void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
mHandler.sendMessage(
mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
}
@@ -4967,12 +4962,17 @@
finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
}
- if (!restarting && hasVisibleActivities
- && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
- // If there was nothing to resume, and we are not already restarting this process, but
- // there is a visible activity that is hosted by the process... then make sure all
- // visible activities are running, taking care of restarting this process.
- mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ mWindowManager.deferSurfaceLayout();
+ try {
+ if (!restarting && hasVisibleActivities
+ && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
+ // If there was nothing to resume, and we are not already restarting this process, but
+ // there is a visible activity that is hosted by the process... then make sure all
+ // visible activities are running, taking care of restarting this process.
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ }
+ } finally {
+ mWindowManager.continueSurfaceLayout();
}
}
@@ -6602,39 +6602,12 @@
}
@Override
- public void keyguardWaitingForActivityDrawn() {
- enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- if (DEBUG_LOCKSCREEN) logLockScreen("");
- mWindowManager.keyguardWaitingForActivityDrawn();
- if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
- mLockScreenShown = LOCK_SCREEN_LEAVING;
- updateSleepIfNeededLocked();
- }
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
public void keyguardGoingAway(int flags) {
enforceNotIsolatedCaller("keyguardGoingAway");
final long token = Binder.clearCallingIdentity();
try {
synchronized (this) {
- if (DEBUG_LOCKSCREEN) logLockScreen("");
- mWindowManager.keyguardGoingAway(flags);
- if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
- mLockScreenShown = LOCK_SCREEN_HIDDEN;
- updateSleepIfNeededLocked();
-
- // Some stack visibility might change (e.g. docked stack)
- mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- applyVrModeIfNeededLocked(mStackSupervisor.getResumedActivityLocked(), true);
- }
+ mKeyguardController.keyguardGoingAway(flags);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -6785,6 +6758,7 @@
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityRecord.activityResumedLocked(token);
+ mWindowManager.notifyAppResumedFinished(token);
}
Binder.restoreCallingIdentity(origId);
}
@@ -11524,7 +11498,7 @@
case PowerManagerInternal.WAKEFULNESS_DOZING:
// Pause applications whenever the lock screen is shown or any sleep
// tokens have been acquired.
- return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
+ return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
case PowerManagerInternal.WAKEFULNESS_ASLEEP:
default:
// If we're asleep then pause applications unconditionally.
@@ -11592,22 +11566,6 @@
Binder.restoreCallingIdentity(origId);
}
- private String lockScreenShownToString() {
- switch (mLockScreenShown) {
- case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
- case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
- case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
- default: return "Unknown=" + mLockScreenShown;
- }
- }
-
- void logLockScreen(String msg) {
- if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
- + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
- + " mSleeping=" + mSleeping);
- }
-
void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
Slog.d(TAG, "<<< startRunningVoiceLocked()");
mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
@@ -11625,7 +11583,8 @@
mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
}
- public void setLockScreenShown(boolean showing, boolean occluded) {
+ @Override
+ public void setLockScreenShown(boolean showing) {
if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
@@ -11635,18 +11594,7 @@
synchronized(this) {
long ident = Binder.clearCallingIdentity();
try {
- if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
- mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
- if (showing && occluded) {
- // The lock screen is currently showing, but is occluded by a window that can
- // show on top of the lock screen. In this can we want to dismiss the docked
- // stack since it will be complicated/risky to try to put the activity on top
- // of the lock screen in the right fullscreen configuration.
- mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
- mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
- }
-
- updateSleepIfNeededLocked();
+ mKeyguardController.setKeyguardShown(showing);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -14652,8 +14600,7 @@
pw.println(" mWakefulness="
+ PowerManagerInternal.wakefulnessToString(mWakefulness));
pw.println(" mSleepTokens=" + mSleepTokens);
- pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
- + lockScreenShownToString());
+ pw.println(" mSleeping=" + mSleeping);
pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
if (mRunningVoice != null) {
pw.println(" mRunningVoice=" + mRunningVoice);
@@ -22091,6 +22038,21 @@
public int getUidProcessState(int uid) {
return getUidState(uid);
}
+
+ @Override
+ public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
+ synchronized (ActivityManagerService.this) {
+
+ // We might change the visibilities here, so prepare an empty app transition which
+ // might be overridden later if we actually change visibilities.
+ mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ mWindowManager.executeAppTransition();
+ }
+ if (callback != null) {
+ callback.run();
+ }
+ }
}
private final class SleepTokenImpl extends SleepToken {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index df03af2..90b46ed 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -83,6 +83,7 @@
import android.view.AppTransitionAnimationSpec;
import android.view.IApplicationToken;
import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.ReferrerIntent;
@@ -721,7 +722,7 @@
: android.R.style.Theme_Holo;
}
if ((aInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
- windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
if ((aInfo.flags&ActivityInfo.FLAG_MULTIPROCESS) != 0
&& _caller != null
@@ -929,6 +930,22 @@
return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
}
+ /**
+ * @return true if the activity contains windows that have
+ * {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set
+ */
+ boolean hasShowWhenLockedWindows() {
+ return service.mWindowManager.containsShowWhenLockedWindow(appToken);
+ }
+
+ /**
+ * @return true if the activity contains windows that have
+ * {@link LayoutParams#FLAG_DISMISS_KEYGUARD} set
+ */
+ boolean hasDismissKeyguardWindows() {
+ return service.mWindowManager.containsDismissKeyguardWindow(appToken);
+ }
+
void makeFinishingLocked() {
if (!finishing) {
final ActivityStack stack = getStack();
@@ -1334,7 +1351,6 @@
if (nowVisible) {
// We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
mStackSupervisor.reportActivityVisibleLocked(this);
- mStackSupervisor.notifyActivityDrawnForKeyguard();
}
// Schedule an idle timeout in case the app doesn't do it for us.
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index fc41fd3..ffe2185 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -31,7 +31,6 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_APP;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
@@ -60,7 +59,6 @@
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.STARTING_WINDOW_REMOVED;
@@ -332,6 +330,9 @@
private final LaunchingTaskPositioner mTaskPositioner;
+ private boolean mTopActivityOccludesKeyguard;
+ private ActivityRecord mTopDismissingKeyguardActivity;
+
static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
@@ -1169,7 +1170,12 @@
if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
- completePauseLocked(true, null);
+ mService.mWindowManager.deferSurfaceLayout();
+ try {
+ completePauseLocked(true, null);
+ } finally {
+ mService.mWindowManager.continueSurfaceLayout();
+ }
return;
} else {
EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
@@ -1581,153 +1587,218 @@
*/
final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
boolean preserveWindows) {
- ActivityRecord top = topRunningActivityLocked();
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
- + " configChanges=0x" + Integer.toHexString(configChanges));
- if (top != null) {
- checkTranslucentActivityWaiting(top);
- }
+ mTopActivityOccludesKeyguard = false;
+ mTopDismissingKeyguardActivity = null;
+ mStackSupervisor.mKeyguardController.beginActivityVisibilityUpdate();
+ try {
+ ActivityRecord top = topRunningActivityLocked();
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
+ + " configChanges=0x" + Integer.toHexString(configChanges));
+ if (top != null) {
+ checkTranslucentActivityWaiting(top);
+ }
- // If the top activity is not fullscreen, then we need to
- // make sure any activities under it are now visible.
- boolean aboveTop = top != null;
- final int stackVisibility = getStackVisibilityLocked(starting);
- final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
- final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND;
- boolean behindFullscreenActivity = stackInvisible;
- boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this)
- && (isInStackLocked(starting) == null);
- boolean behindTranslucentActivity = false;
- final ActivityRecord visibleBehind = getVisibleBehindActivity();
- for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- final TaskRecord task = mTaskHistory.get(taskNdx);
- final ArrayList<ActivityRecord> activities = task.mActivities;
- for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
- final ActivityRecord r = activities.get(activityNdx);
- if (r.finishing) {
- // Normally the screenshot will be taken in makeInvisible(). When an activity
- // is finishing, we no longer change its visibility, but we still need to take
- // the screenshots if startPausingLocked decided it should be taken.
- if (r.mUpdateTaskThumbnailWhenHidden) {
- r.updateThumbnailLocked(r.screenshotActivityLocked(),
- null /* description */);
- r.mUpdateTaskThumbnailWhenHidden = false;
+ // If the top activity is not fullscreen, then we need to
+ // make sure any activities under it are now visible.
+ boolean aboveTop = top != null;
+ final int stackVisibility = getStackVisibilityLocked(starting);
+ final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
+ final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND;
+ boolean behindFullscreenActivity = stackInvisible;
+ boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this)
+ && (isInStackLocked(starting) == null);
+ boolean behindTranslucentActivity = false;
+ final ActivityRecord visibleBehind = getVisibleBehindActivity();
+ for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+ final TaskRecord task = mTaskHistory.get(taskNdx);
+ final ArrayList<ActivityRecord> activities = task.mActivities;
+ for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+ final ActivityRecord r = activities.get(activityNdx);
+ if (r.finishing) {
+ // Normally the screenshot will be taken in makeInvisible(). When an activity
+ // is finishing, we no longer change its visibility, but we still need to take
+ // the screenshots if startPausingLocked decided it should be taken.
+ if (r.mUpdateTaskThumbnailWhenHidden) {
+ r.updateThumbnailLocked(r.screenshotActivityLocked(),
+ null /* description */);
+ r.mUpdateTaskThumbnailWhenHidden = false;
+ }
+ continue;
}
- continue;
- }
- final boolean isTop = r == top;
- if (aboveTop && !isTop) {
- continue;
- }
- aboveTop = false;
-
- if (r.shouldBeVisible(behindTranslucentActivity, stackVisibleBehind,
- visibleBehind, behindFullscreenActivity)) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
- + " finishing=" + r.finishing + " state=" + r.state);
- // First: if this is not the current activity being started, make
- // sure it matches the current configuration.
- if (r != starting) {
- r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindows);
+ final boolean isTop = r == top;
+ if (aboveTop && !isTop) {
+ continue;
}
+ aboveTop = false;
- if (r.app == null || r.app.thread == null) {
- if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
- resumeNextActivity, r)) {
- if (activityNdx >= activities.size()) {
- // Record may be removed if its process needs to restart.
- activityNdx = activities.size() - 1;
- } else {
+ // Check whether activity should be visible without Keyguard influence
+ final boolean shouldBeVisible = r.shouldBeVisible(behindTranslucentActivity,
+ stackVisibleBehind, visibleBehind, behindFullscreenActivity);
+
+ // Now check whether it's really visible depending on Keyguard state.
+ final boolean reallyVisible = checkKeyguardVisibility(r, shouldBeVisible,
+ isTop);
+ if (shouldBeVisible) {
+ behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
+ behindFullscreenActivity, task, r);
+ if (behindFullscreenActivity && !r.fullscreen) {
+ behindTranslucentActivity = true;
+ }
+ }
+ if (reallyVisible) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
+ + " finishing=" + r.finishing + " state=" + r.state);
+ // First: if this is not the current activity being started, make
+ // sure it matches the current configuration.
+ if (r != starting) {
+ r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindows);
+ }
+
+ if (r.app == null || r.app.thread == null) {
+ if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
+ resumeNextActivity, r)) {
+ if (activityNdx >= activities.size()) {
+ // Record may be removed if its process needs to restart.
+ activityNdx = activities.size() - 1;
+ } else {
+ resumeNextActivity = false;
+ }
+ }
+ } else if (r.visible) {
+ // If this activity is already visible, then there is nothing to do here.
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
+ "Skipping: already visible at " + r);
+
+ if (r.handleAlreadyVisible()) {
resumeNextActivity = false;
}
+ } else {
+ r.makeVisibleIfNeeded(starting);
}
- } else if (r.visible) {
- // If this activity is already visible, then there is nothing to do here.
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
- "Skipping: already visible at " + r);
-
- if (r.handleAlreadyVisible()) {
- resumeNextActivity = false;
- }
+ // Aggregate current change flags.
+ configChanges |= r.configChangeFlags;
} else {
- r.makeVisibleIfNeeded(starting);
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
+ + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible="
+ + stackInvisible + " behindFullscreenActivity="
+ + behindFullscreenActivity + " mLaunchTaskBehind="
+ + r.mLaunchTaskBehind);
+ makeInvisible(r, visibleBehind);
}
- // Aggregate current change flags.
- configChanges |= r.configChangeFlags;
- behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
- behindFullscreenActivity, task, r);
- if (behindFullscreenActivity && !r.fullscreen) {
- behindTranslucentActivity = true;
+ }
+ if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+ // The visibility of tasks and the activities they contain in freeform stack are
+ // determined individually unlike other stacks where the visibility or fullscreen
+ // status of an activity in a previous task affects other.
+ behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
+ } else if (mStackId == HOME_STACK_ID) {
+ if (task.isOnTopLauncher()) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "On-top launcher: at " + task
+ + " stackInvisible=" + stackInvisible
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
+ // When an on-top launcher is visible, (e.g. it's on the top of the home stack),
+ // other tasks in the home stack could be visible if and only if:
+ // - some app is running in the docked stack;
+ // - no app is running in either the fullscreen stack or the freefrom stack.
+ final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
+ final ActivityStack fullscreenStack = mStackSupervisor.getStack(
+ FULLSCREEN_WORKSPACE_STACK_ID);
+ final ActivityStack freeformStack = mStackSupervisor.getStack(
+ FREEFORM_WORKSPACE_STACK_ID);
+ final boolean dockedStackEmpty = dockedStack == null ||
+ dockedStack.topRunningActivityLocked() == null;
+ final boolean fullscreenStackEmpty = fullscreenStack == null ||
+ fullscreenStack.topRunningActivityLocked() == null;
+ final boolean freeformStackEmpty = freeformStack == null ||
+ freeformStack.topRunningActivityLocked() == null;
+ behindFullscreenActivity = dockedStackEmpty || !fullscreenStackEmpty ||
+ !freeformStackEmpty;
+ } else if (task.isHomeTask()) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
+ + " stackInvisible=" + stackInvisible
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
+ // No other task in the home stack should be visible behind the home activity.
+ // Home activities is usually a translucent activity with the wallpaper behind
+ // them. However, when they don't have the wallpaper behind them, we want to
+ // show activities in the next application stack behind them vs. another
+ // task in the home stack like recents.
+ behindFullscreenActivity = true;
+ } else if (task.isRecentsTask()
+ && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
+ "Recents task returning to app: at " + task
+ + " stackInvisible=" + stackInvisible
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
+ // We don't want any other tasks in the home stack visible if the recents
+ // activity is going to be returning to an application activity type.
+ // We do this to preserve the visible order the user used to get into the
+ // recents activity. The recents activity is normally translucent and if it
+ // doesn't have the wallpaper behind it the next activity in the home stack
+ // shouldn't be visible when the home stack is brought to the front to display
+ // the recents activity from an app.
+ behindFullscreenActivity = true;
}
- } else {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
- + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible="
- + stackInvisible + " behindFullscreenActivity="
- + behindFullscreenActivity + " mLaunchTaskBehind="
- + r.mLaunchTaskBehind);
- makeInvisible(r, visibleBehind);
+
}
}
- if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
- // The visibility of tasks and the activities they contain in freeform stack are
- // determined individually unlike other stacks where the visibility or fullscreen
- // status of an activity in a previous task affects other.
- behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
- } else if (mStackId == HOME_STACK_ID) {
- if (task.isOnTopLauncher()) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "On-top launcher: at " + task
- + " stackInvisible=" + stackInvisible
- + " behindFullscreenActivity=" + behindFullscreenActivity);
- // When an on-top launcher is visible, (e.g. it's on the top of the home stack),
- // other tasks in the home stack could be visible if and only if:
- // - some app is running in the docked stack;
- // - no app is running in either the fullscreen stack or the freefrom stack.
- final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
- final ActivityStack fullscreenStack = mStackSupervisor.getStack(
- FULLSCREEN_WORKSPACE_STACK_ID);
- final ActivityStack freeformStack = mStackSupervisor.getStack(
- FREEFORM_WORKSPACE_STACK_ID);
- final boolean dockedStackEmpty = dockedStack == null ||
- dockedStack.topRunningActivityLocked() == null;
- final boolean fullscreenStackEmpty = fullscreenStack == null ||
- fullscreenStack.topRunningActivityLocked() == null;
- final boolean freeformStackEmpty = freeformStack == null ||
- freeformStack.topRunningActivityLocked() == null;
- behindFullscreenActivity = dockedStackEmpty || !fullscreenStackEmpty ||
- !freeformStackEmpty;
- } else if (task.isHomeTask()) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
- + " stackInvisible=" + stackInvisible
- + " behindFullscreenActivity=" + behindFullscreenActivity);
- // No other task in the home stack should be visible behind the home activity.
- // Home activities is usually a translucent activity with the wallpaper behind
- // them. However, when they don't have the wallpaper behind them, we want to
- // show activities in the next application stack behind them vs. another
- // task in the home stack like recents.
- behindFullscreenActivity = true;
- } else if (task.isRecentsTask()
- && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
- "Recents task returning to app: at " + task
- + " stackInvisible=" + stackInvisible
- + " behindFullscreenActivity=" + behindFullscreenActivity);
- // We don't want any other tasks in the home stack visible if the recents
- // activity is going to be returning to an application activity type.
- // We do this to preserve the visible order the user used to get into the
- // recents activity. The recents activity is normally translucent and if it
- // doesn't have the wallpaper behind it the next activity in the home stack
- // shouldn't be visible when the home stack is brought to the front to display
- // the recents activity from an app.
- behindFullscreenActivity = true;
- }
+ if (mTranslucentActivityWaiting != null &&
+ mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
+ // Nothing is getting drawn or everything was already visible, don't wait for timeout.
+ notifyActivityDrawnLocked(null);
+ }
+ } finally {
+ mStackSupervisor.mKeyguardController.endActivityVisibilityUpdate();
+ }
+ }
+
+ /**
+ * @return true if the top visible activity wants to occlude the Keyguard, false otherwise
+ */
+ boolean topActivityOccludesKeyguard() {
+ return mTopActivityOccludesKeyguard;
+ }
+
+ /**
+ * @return the top most visible activity that wants to dismiss Keyguard
+ */
+ ActivityRecord getTopDismissingKeyguardActivity() {
+ return mTopDismissingKeyguardActivity;
+ }
+
+ /**
+ * Checks whether {@param r} should be visible depending on Keyguard state and updates
+ * {@link #mTopActivityOccludesKeyguard} and {@link #mTopDismissingKeyguardActivity} if
+ * necessary.
+ *
+ * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
+ */
+ private boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible,
+ boolean isTop) {
+ final boolean keyguardShowing = mStackSupervisor.mKeyguardController.isKeyguardShowing();
+ final boolean keyguardLocked = mStackSupervisor.mKeyguardController.isKeyguardLocked();
+ final boolean showWhenLocked = r.hasShowWhenLockedWindows();
+ if (shouldBeVisible) {
+ if (r.hasDismissKeyguardWindows() && mTopDismissingKeyguardActivity == null) {
+ mTopDismissingKeyguardActivity = r;
+ }
+
+ // Only the top activity may control occluded, as we can't occlude the Keyguard if the
+ // top app doesn't want to occlude it.
+ if (isTop) {
+ mTopActivityOccludesKeyguard |= showWhenLocked;
}
}
+ if (keyguardShowing) {
- if (mTranslucentActivityWaiting != null &&
- mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
- // Nothing is getting drawn or everything was already visible, don't wait for timeout.
- notifyActivityDrawnLocked(null);
+ // If keyguard is showing, nothing is visible.
+ return false;
+ } else if (keyguardLocked) {
+
+ // Show when locked windows above keyguard.
+ return shouldBeVisible && showWhenLocked;
+ } else {
+ return shouldBeVisible;
}
}
@@ -1947,10 +2018,6 @@
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
- if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
- mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
- mService.updateSleepIfNeededLocked();
- }
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
@@ -1969,8 +2036,6 @@
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
- if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
-
if (!mService.mBooting && !mService.mBooted) {
// Not ready yet!
return false;
@@ -3287,72 +3352,77 @@
return false;
}
- r.makeFinishingLocked();
- final TaskRecord task = r.task;
- EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
- r.userId, System.identityHashCode(r),
- task.taskId, r.shortComponentName, reason);
- final ArrayList<ActivityRecord> activities = task.mActivities;
- final int index = activities.indexOf(r);
- if (index < (activities.size() - 1)) {
- task.setFrontOfTask();
- if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
- // If the caller asked that this activity (and all above it)
- // be cleared when the task is reset, don't lose that information,
- // but propagate it up to the next activity.
- ActivityRecord next = activities.get(index+1);
- next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ mWindowManager.deferSurfaceLayout();
+ try {
+ r.makeFinishingLocked();
+ final TaskRecord task = r.task;
+ EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
+ r.userId, System.identityHashCode(r),
+ task.taskId, r.shortComponentName, reason);
+ final ArrayList<ActivityRecord> activities = task.mActivities;
+ final int index = activities.indexOf(r);
+ if (index < (activities.size() - 1)) {
+ task.setFrontOfTask();
+ if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
+ // If the caller asked that this activity (and all above it)
+ // be cleared when the task is reset, don't lose that information,
+ // but propagate it up to the next activity.
+ ActivityRecord next = activities.get(index+1);
+ next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ }
}
- }
- r.pauseKeyDispatchingLocked();
+ r.pauseKeyDispatchingLocked();
- adjustFocusedActivityStackLocked(r, "finishActivity");
+ adjustFocusedActivityStackLocked(r, "finishActivity");
- finishActivityResultsLocked(r, resultCode, resultData);
+ finishActivityResultsLocked(r, resultCode, resultData);
- final boolean endTask = index <= 0;
- final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
- if (mResumedActivity == r) {
- if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
- "Prepare close transition: finishing " + r);
+ final boolean endTask = index <= 0;
+ final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
+ if (mResumedActivity == r) {
+ if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
+ "Prepare close transition: finishing " + r);
if (endTask) {
mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(task.taskId);
}
- mWindowManager.prepareAppTransition(transit, false);
-
- // Tell window manager to prepare for this one to be removed.
- mWindowManager.setAppVisibility(r.appToken, false);
-
- if (mPausingActivity == null) {
- if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
- if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
- "finish() => pause with userLeaving=false");
- startPausingLocked(false, false, null, false);
- }
-
- if (endTask) {
- mStackSupervisor.removeLockedTaskLocked(task);
- }
- } else if (r.state != ActivityState.PAUSING) {
- // If the activity is PAUSING, we will complete the finish once
- // it is done pausing; else we can just directly finish it here.
- if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
- if (r.visible) {
mWindowManager.prepareAppTransition(transit, false);
- mWindowManager.setAppVisibility(r.appToken, false);
- mWindowManager.executeAppTransition();
- if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
- mStackSupervisor.mWaitingVisibleActivities.add(r);
- }
- }
- return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
- FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
- } else {
- if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
- }
- return false;
+ // Tell window manager to prepare for this one to be removed.
+ mWindowManager.setAppVisibility(r.appToken, false);
+
+ if (mPausingActivity == null) {
+ if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
+ if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
+ "finish() => pause with userLeaving=false");
+ startPausingLocked(false, false, null, false);
+ }
+
+ if (endTask) {
+ mStackSupervisor.removeLockedTaskLocked(task);
+ }
+ } else if (r.state != ActivityState.PAUSING) {
+ // If the activity is PAUSING, we will complete the finish once
+ // it is done pausing; else we can just directly finish it here.
+ if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
+ if (r.visible) {
+ mWindowManager.prepareAppTransition(transit, false);
+ mWindowManager.setAppVisibility(r.appToken, false);
+ mWindowManager.executeAppTransition();
+ if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
+ mStackSupervisor.mWaitingVisibleActivities.add(r);
+ }
+ }
+ return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
+ FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
+ } else {
+ if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
+ }
+
+ return false;
+ } finally {
+ mWindowManager.continueSurfaceLayout();
+ }
}
static final int FINISH_IMMEDIATELY = 0;
@@ -4762,7 +4832,8 @@
voiceInteractor);
// add the task to stack first, mTaskPositioner might need the stack association
addTask(task, toTop, "createTaskRecord");
- final boolean isLockscreenShown = mService.mLockScreenShown == LOCK_SCREEN_SHOWN;
+ final boolean isLockscreenShown =
+ mService.mStackSupervisor.mKeyguardController.isKeyguardShowing();
if (!layoutTaskInStack(task, info.windowLayout) && mBounds != null && task.isResizeable()
&& !isLockscreenShown) {
task.updateOverrideConfiguration(mBounds);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f0427e4..eed8dd7 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -16,6 +16,79 @@
package com.android.server.am;
+import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
+import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
+import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
+import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
+import static android.app.ActivityManager.RESIZE_MODE_FORCED;
+import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
+import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
+import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityManagerService.ANIMATE;
+import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
+import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
+import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
+import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
+import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
+import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
+import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
+import static com.android.server.am.ActivityStack.STACK_VISIBLE;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
+import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
+
import android.Manifest;
import android.annotation.UserIdInt;
import android.app.Activity;
@@ -26,7 +99,6 @@
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.AppOpsManager;
-import android.app.IActivityContainer;
import android.app.IActivityContainerCallback;
import android.app.IActivityManager;
import android.app.IActivityManager.WaitResult;
@@ -83,7 +155,6 @@
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.Display;
-import android.view.DisplayInfo;
import android.view.InputEvent;
import android.view.Surface;
@@ -106,79 +177,7 @@
import java.util.Objects;
import java.util.Set;
-import static android.Manifest.permission.START_ANY_ACTIVITY;
-import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
-import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
-import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
-import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
-import static android.app.ActivityManager.RESIZE_MODE_FORCED;
-import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
-import static android.app.ActivityManager.START_TASK_TO_FRONT;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
-import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.HOME_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityManagerService.ANIMATE;
-import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
-import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
-import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
-import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
-import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
-import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
-import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
-import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
-import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
-import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
-import static com.android.server.am.ActivityStack.STACK_VISIBLE;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
-import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
-
-public final class ActivityStackSupervisor extends ConfigurationContainer
+public class ActivityStackSupervisor extends ConfigurationContainer
implements DisplayListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
@@ -477,6 +476,8 @@
*/
boolean mIsDockMinimized;
+ final KeyguardController mKeyguardController;
+
/**
* Description of a request to start a new activity, which has been held
* due to app switches being disabled.
@@ -514,6 +515,7 @@
mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
mResizeDockedStackTimeout = new ResizeDockedStackTimeout(service, this, mHandler);
+ mKeyguardController = new KeyguardController(service, this);
}
void setRecentTasks(RecentTasks recentTasks) {
@@ -562,6 +564,7 @@
void setWindowManager(WindowManagerService wm) {
synchronized (mService) {
mWindowManager = wm;
+ mKeyguardController.setWindowManager(wm);
mDisplayManager =
(DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
@@ -585,11 +588,6 @@
}
}
- void notifyActivityDrawnForKeyguard() {
- if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
- mWindowManager.notifyActivityDrawnForKeyguard();
- }
-
ActivityStack getFocusedStack() {
return mFocusedStack;
}
@@ -1224,6 +1222,10 @@
displayId);
}
+ if (mKeyguardController.isKeyguardLocked()) {
+ mWindowManager.notifyUnknownAppVisibilityLaunched(r.appToken);
+ }
+
r.app = app;
app.waitingToKill = null;
r.launchCount++;
@@ -1944,7 +1946,7 @@
return null;
}
// TODO(multi-display): Allow creating stacks on secondary displays.
- return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop);
+ return createStackOnDisplay(stackId, DEFAULT_DISPLAY, createOnTop);
}
ArrayList<ActivityStack> getStacks() {
@@ -1955,6 +1957,10 @@
return allStacks;
}
+ ArrayList<ActivityStack> getStacksOnDefaultDisplay() {
+ return mActivityDisplays.valueAt(DEFAULT_DISPLAY).mStacks;
+ }
+
ActivityRecord getHomeActivity() {
return getHomeActivityForUser(mCurrentUser);
}
@@ -2919,14 +2925,19 @@
void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
boolean preserveWindows) {
- // First the front stacks. In case any are not fullscreen and are in front of home.
- for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
- final int topStackNdx = stacks.size() - 1;
- for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = stacks.get(stackNdx);
- stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
+ mKeyguardController.beginActivityVisibilityUpdate();
+ try {
+ // First the front stacks. In case any are not fullscreen and are in front of home.
+ for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
+ final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
+ final int topStackNdx = stacks.size() - 1;
+ for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = stacks.get(stackNdx);
+ stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
+ }
}
+ } finally {
+ mKeyguardController.endActivityVisibilityUpdate();
}
}
@@ -3157,15 +3168,16 @@
pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
- final SparseArray<String[]> packages = mService.mLockTaskPackages;
- if (packages.size() > 0) {
- pw.println(" mLockTaskPackages (userId:packages)=");
- for (int i = 0; i < packages.size(); ++i) {
- pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
- pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
- }
- }
- pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
+ final SparseArray<String[]> packages = mService.mLockTaskPackages;
+ if (packages.size() > 0) {
+ pw.print(prefix); pw.println("mLockTaskPackages (userId:packages)=");
+ for (int i = 0; i < packages.size(); ++i) {
+ pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
+ pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
+ }
+ }
+ pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
+ mKeyguardController.dump(pw, prefix);
}
/**
@@ -3470,10 +3482,10 @@
}
private StackInfo getStackInfoLocked(ActivityStack stack) {
- final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
+ final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
StackInfo info = new StackInfo();
mWindowManager.getStackBounds(stack.mStackId, info.bounds);
- info.displayId = Display.DEFAULT_DISPLAY;
+ info.displayId = DEFAULT_DISPLAY;
info.stackId = stack.mStackId;
info.userId = stack.mCurrentUser;
info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE;
@@ -4390,7 +4402,7 @@
ActivityStack findStackBehind(ActivityStack stack) {
// TODO(multi-display): We are only looking for stacks on the default display.
- final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
+ final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
if (display == null) {
return null;
}
@@ -4505,7 +4517,7 @@
public List<IBinder> getTopVisibleActivities() {
// TODO(multi-display): Get rid of DEFAULT_DISPLAY here. Used in
// VoiceInteractionManagerServiceImpl#showSessionLocked.
- final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
+ final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
if (display == null) {
return Collections.EMPTY_LIST;
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 006c13d..db73048 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -577,10 +577,6 @@
ActivityStack targetStack) {
if (result < START_SUCCESS) {
- // If someone asked to have the keyguard dismissed on the next activity start,
- // but we are not actually doing an activity switch... just dismiss the keyguard now,
- // because we probably want to see whatever is behind it.
- mSupervisor.notifyActivityDrawnForKeyguard();
return;
}
@@ -1661,11 +1657,6 @@
private void resumeTargetStackIfNeeded() {
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
- if (!mMovedToFront) {
- // Make sure to notify Keyguard as well if we are not running an app transition
- // later.
- mSupervisor.notifyActivityDrawnForKeyguard();
- }
} else {
ActivityOptions.abort(mOptions);
}
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
new file mode 100644
index 0000000..98acc9c
--- /dev/null
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
+import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
+import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
+import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_OCCLUDE;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
+
+import com.android.server.wm.WindowManagerService;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are
+ * currently visible.
+ * <p>
+ * Note that everything in this class should only be accessed with the AM lock being held.
+ */
+class KeyguardController {
+
+ private final ActivityManagerService mService;
+ private final ActivityStackSupervisor mStackSupervisor;
+ private WindowManagerService mWindowManager;
+ private boolean mKeyguardShowing;
+ private boolean mKeyguardGoingAway;
+ private boolean mOccluded;
+ private ActivityRecord mDismissingKeyguardActivity;
+ private int mBeforeUnoccludeTransit;
+ private int mVisibilityTransactionDepth;
+
+ KeyguardController(ActivityManagerService service,
+ ActivityStackSupervisor stackSupervisor) {
+ mService = service;
+ mStackSupervisor = stackSupervisor;
+ }
+
+ void setWindowManager(WindowManagerService windowManager) {
+ mWindowManager = windowManager;
+ }
+
+ /**
+ * @return true if Keyguard is showing, not going away, and not being occluded, false otherwise
+ */
+ boolean isKeyguardShowing() {
+ return mKeyguardShowing && !mKeyguardGoingAway && !mOccluded;
+ }
+
+ /**
+ * @return true if Keyguard is either showing or occluded, but not going away
+ */
+ boolean isKeyguardLocked() {
+ return mKeyguardShowing && !mKeyguardGoingAway;
+ }
+
+ /**
+ * Update the Keyguard showing state.
+ */
+ void setKeyguardShown(boolean showing) {
+ if (showing == mKeyguardShowing) {
+ return;
+ }
+ mKeyguardShowing = showing;
+ if (showing) {
+ mKeyguardGoingAway = false;
+
+ // Allow an activity to redismiss Keyguard.
+ mDismissingKeyguardActivity = null;
+ }
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ mService.updateSleepIfNeededLocked();
+ }
+
+ /**
+ * Called when Keyguard is going away.
+ *
+ * @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
+ * etc.
+ */
+ void keyguardGoingAway(int flags) {
+ if (mKeyguardShowing) {
+ mWindowManager.deferSurfaceLayout();
+ try {
+ mKeyguardGoingAway = true;
+ mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
+ false /* alwaysKeepCurrent */, convertTransitFlags(flags),
+ false /* forceOverride */);
+ mWindowManager.keyguardGoingAway(flags);
+ mService.updateSleepIfNeededLocked();
+
+ // Some stack visibility might change (e.g. docked stack)
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ mWindowManager.executeAppTransition();
+ mService.applyVrModeIfNeededLocked(mStackSupervisor.getResumedActivityLocked(),
+ true /* enable */);
+ } finally {
+ mWindowManager.continueSurfaceLayout();
+ }
+ }
+ }
+
+ private int convertTransitFlags(int keyguardGoingAwayFlags) {
+ int result = 0;
+ if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0) {
+ result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
+ }
+ if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0) {
+ result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+ }
+ if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) {
+ result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
+ }
+ return result;
+ }
+
+ /**
+ * Starts a batch of visibility updates.
+ */
+ void beginActivityVisibilityUpdate() {
+ mVisibilityTransactionDepth++;
+ }
+
+ /**
+ * Ends a batch of visibility updates. After all batches are done, this method makes sure to
+ * update lockscreen occluded/dismiss state if needed.
+ */
+ void endActivityVisibilityUpdate() {
+ mVisibilityTransactionDepth--;
+ if (mVisibilityTransactionDepth == 0) {
+ visibilitiesUpdated();
+ }
+ }
+
+ private void visibilitiesUpdated() {
+ final boolean lastOccluded = mOccluded;
+ final ActivityRecord lastDismissingKeyguardActivity = mDismissingKeyguardActivity;
+ mOccluded = false;
+ mDismissingKeyguardActivity = null;
+ final ArrayList<ActivityStack> stacks = mStackSupervisor.getStacksOnDefaultDisplay();
+ final int topStackNdx = stacks.size() - 1;
+ for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = stacks.get(stackNdx);
+
+ // Only the very top activity may control occluded state
+ if (stackNdx == topStackNdx) {
+ mOccluded = stack.topActivityOccludesKeyguard();
+ }
+ if (mDismissingKeyguardActivity == null
+ && stack.getTopDismissingKeyguardActivity() != null) {
+ mDismissingKeyguardActivity = stack.getTopDismissingKeyguardActivity();
+ }
+ }
+ mOccluded |= mWindowManager.isShowingDream();
+ if (mOccluded != lastOccluded) {
+ handleOccludedChanged();
+ }
+ if (mDismissingKeyguardActivity != lastDismissingKeyguardActivity) {
+ handleDismissKeyguard();
+ }
+ }
+
+ /**
+ * Called when occluded state changed.
+ */
+ private void handleOccludedChanged() {
+ mWindowManager.onKeyguardOccludedChanged(mOccluded);
+ if (isKeyguardLocked()) {
+ mWindowManager.deferSurfaceLayout();
+ try {
+ mWindowManager.prepareAppTransition(resolveOccludeTransit(),
+ false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */);
+ mService.updateSleepIfNeededLocked();
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ mWindowManager.executeAppTransition();
+ } finally {
+ mWindowManager.continueSurfaceLayout();
+ }
+ }
+ dismissDockedStackIfNeeded();
+ }
+
+ /**
+ * Called when somebody might want to dismiss the Keyguard.
+ */
+ private void handleDismissKeyguard() {
+ if (mDismissingKeyguardActivity != null) {
+ mWindowManager.dismissKeyguard();
+
+ // If we are about to unocclude the Keyguard, but we can dismiss it without security,
+ // we immediately dismiss the Keyguard so the activity gets shown without a flicker.
+ if (mKeyguardShowing && canDismissKeyguard()
+ && mWindowManager.getPendingAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) {
+ mWindowManager.prepareAppTransition(mBeforeUnoccludeTransit,
+ false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */);
+ mKeyguardGoingAway = true;
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ mWindowManager.executeAppTransition();
+ }
+ }
+ }
+
+ /**
+ * @return true if Keyguard can be currently dismissed without entering credentials.
+ */
+ private boolean canDismissKeyguard() {
+ return mWindowManager.isKeyguardTrusted() || !mWindowManager.isKeyguardSecure();
+ }
+
+ private int resolveOccludeTransit() {
+ if (mBeforeUnoccludeTransit != TRANSIT_UNSET
+ && mWindowManager.getPendingAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE
+ && mOccluded) {
+
+ // Reuse old transit in case we are occluding Keyguard again, meaning that we never
+ // actually occclude/unocclude Keyguard, but just run a normal transition.
+ return mBeforeUnoccludeTransit;
+ } else if (!mOccluded) {
+
+ // Save transit in case we dismiss/occlude Keyguard shortly after.
+ mBeforeUnoccludeTransit = mWindowManager.getPendingAppTransition();
+ return TRANSIT_KEYGUARD_UNOCCLUDE;
+ } else {
+ return TRANSIT_KEYGUARD_OCCLUDE;
+ }
+ }
+
+ private void dismissDockedStackIfNeeded() {
+ if (mKeyguardShowing && mOccluded) {
+ // The lock screen is currently showing, but is occluded by a window that can
+ // show on top of the lock screen. In this can we want to dismiss the docked
+ // stack since it will be complicated/risky to try to put the activity on top
+ // of the lock screen in the right fullscreen configuration.
+ mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
+ mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
+ }
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "KeyguardController:");
+ pw.println(prefix + " mKeyguardShowing=" + mKeyguardShowing);
+ pw.println(prefix + " mKeyguardGoingAway=" + mKeyguardGoingAway);
+ pw.println(prefix + " mOccluded=" + mOccluded);
+ pw.println(prefix + " mDismissingKeyguardActivity=" + mDismissingKeyguardActivity);
+ pw.println(prefix + " mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
+ }
+}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index b37b3f0..86e3ccc 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -56,8 +56,6 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
import java.util.Objects;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
@@ -89,7 +87,6 @@
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
@@ -1700,7 +1697,7 @@
/** Returns the bounds that should be used to launch this task. */
Rect getLaunchBounds() {
// If we're over lockscreen, forget about stack bounds and use fullscreen.
- if (mService.mLockScreenShown == LOCK_SCREEN_SHOWN) {
+ if (mService.mStackSupervisor.mKeyguardController.isKeyguardShowing()) {
return null;
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 40dfcda..41fd16b 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -25,13 +25,82 @@
import static android.content.res.Configuration.EMPTY;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
-import static android.view.WindowManager.DOCKED_TOP;
import static android.view.WindowManager.DOCKED_LEFT;
import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
+import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
+import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
+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_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
+import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
-import static android.view.WindowManager.LayoutParams.*;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
@@ -39,6 +108,7 @@
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.StackId;
import android.app.ActivityManagerInternal;
@@ -112,10 +182,10 @@
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
+import android.util.LongSparseArray;
import android.util.MutableBoolean;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.LongSparseArray;
import android.view.Display;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
@@ -133,19 +203,21 @@
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerInternal;
+import android.view.WindowManagerInternal.AppTransitionListener;
import android.view.WindowManagerPolicy;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
+
import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.policy.PhoneWindow;
import com.android.internal.policy.IShortcutService;
+import com.android.internal.policy.PhoneWindow;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.widget.PointerLocationView;
@@ -154,12 +226,12 @@
import com.android.server.policy.keyguard.KeyguardServiceDelegate;
import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
import com.android.server.statusbar.StatusBarManagerInternal;
+import com.android.server.wm.AppTransition;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
-import java.util.HashSet;
import java.util.List;
/**
@@ -280,8 +352,6 @@
/**
* Keyguard stuff
*/
- private WindowState mKeyguardScrim;
- private boolean mKeyguardHidden;
private boolean mKeyguardDrawnOnce;
/* Table of Application Launch keys. Maps from key codes to intent categories.
@@ -582,54 +652,23 @@
WindowState mTopFullscreenOpaqueOrDimmingWindowState;
WindowState mTopDockedOpaqueWindowState;
WindowState mTopDockedOpaqueOrDimmingWindowState;
- HashSet<IApplicationToken> mAppsToBeHidden = new HashSet<IApplicationToken>();
- HashSet<IApplicationToken> mAppsThatDismissKeyguard = new HashSet<IApplicationToken>();
boolean mTopIsFullscreen;
boolean mForceStatusBar;
boolean mForceStatusBarFromKeyguard;
private boolean mForceStatusBarTransparent;
int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED;
- boolean mHideLockScreen;
boolean mForcingShowNavBar;
int mForcingShowNavBarLayer;
- // States of keyguard dismiss.
- private static final int DISMISS_KEYGUARD_NONE = 0; // Keyguard not being dismissed.
- private static final int DISMISS_KEYGUARD_START = 1; // Keyguard needs to be dismissed.
- private static final int DISMISS_KEYGUARD_CONTINUE = 2; // Keyguard has been dismissed.
- int mDismissKeyguard = DISMISS_KEYGUARD_NONE;
+ private boolean mPendingKeyguardOccluded;
+ private boolean mKeyguardOccludedChanged;
- /**
- * Indicates that we asked the Keyguard to be dismissed and we just wait for the Keyguard to
- * dismiss itself.
- */
- @GuardedBy("Lw")
- private boolean mCurrentlyDismissingKeyguard;
-
- /** The window that is currently dismissing the keyguard. Dismissing the keyguard must only
- * be done once per window. */
- private WindowState mWinDismissingKeyguard;
-
- /** When window is currently dismissing the keyguard, dismissing the keyguard must handle
- * the keygaurd secure state change instantly case, e.g. the use case of inserting a PIN
- * lock SIM card. This variable is used to record the previous keyguard secure state for
- * monitoring secure state change on window dismissing keyguard. */
- private boolean mSecureDismissingKeyguard;
-
- /** The window that is currently showing "over" the keyguard. If there is an app window
- * belonging to another app on top of this the keyguard shows. If there is a fullscreen
- * app window under this, still dismiss the keyguard but don't show the app underneath. Show
- * the wallpaper. */
- private WindowState mWinShowWhenLocked;
-
- boolean mShowingLockscreen;
boolean mShowingDream;
+ private boolean mLastShowingDream;
boolean mDreamingLockscreen;
boolean mDreamingSleepTokenNeeded;
SleepToken mDreamingSleepToken;
SleepToken mScreenOffSleepToken;
- boolean mKeyguardSecure;
- boolean mKeyguardSecureIncludingHidden;
volatile boolean mKeyguardOccluded;
boolean mHomePressed;
boolean mHomeConsumed;
@@ -1911,6 +1950,19 @@
mWindowManagerInternal.registerAppTransitionListener(
mStatusBarController.getAppTransitionListener());
+ mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
+ @Override
+ public int onAppTransitionStartingLocked(int transit, IBinder openToken,
+ IBinder closeToken,
+ Animation openAnimation, Animation closeAnimation) {
+ return handleStartTransitionForKeyguardLw(transit, openAnimation);
+ }
+
+ @Override
+ public void onAppTransitionCancelledLocked(int transit) {
+ handleStartTransitionForKeyguardLw(transit, null /* transit */);
+ }
+ });
}
/**
@@ -2316,7 +2368,6 @@
case TYPE_BOOT_PROGRESS:
case TYPE_DISPLAY_OVERLAY:
case TYPE_INPUT_CONSUMER:
- case TYPE_KEYGUARD_SCRIM:
case TYPE_KEYGUARD_DIALOG:
case TYPE_MAGNIFICATION_OVERLAY:
case TYPE_NAVIGATION_BAR:
@@ -2357,7 +2408,7 @@
// remove the wallpaper and keyguard flag so that any change in-flight after setting
// the keyguard as occluded wouldn't set these flags again.
// See {@link #processKeyguardSetHiddenResultLw}.
- if (mKeyguardHidden) {
+ if (mKeyguardOccluded) {
attrs.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
}
@@ -2533,9 +2584,6 @@
case TYPE_INPUT_METHOD_DIALOG:
// on-screen keyboards and other such input method user interfaces go here.
return 13;
- case TYPE_KEYGUARD_SCRIM:
- // the safety window that shows behind keyguard while keyguard is starting
- return 14;
case TYPE_STATUS_BAR_SUB_PANEL:
return 15;
case TYPE_STATUS_BAR:
@@ -2673,26 +2721,17 @@
}
@Override
- public boolean isForceHiding(WindowManager.LayoutParams attrs) {
- return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
- (isKeyguardHostWindow(attrs) &&
- (mKeyguardDelegate != null && mKeyguardDelegate.isShowing())) ||
- (attrs.type == TYPE_KEYGUARD_SCRIM);
- }
-
- @Override
public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
return attrs.type == TYPE_STATUS_BAR;
}
@Override
- public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
- switch (attrs.type) {
+ public boolean canBeHiddenByKeyguardLw(WindowState win) {
+ switch (win.getAttrs().type) {
case TYPE_STATUS_BAR:
case TYPE_NAVIGATION_BAR:
case TYPE_WALLPAPER:
case TYPE_DREAM:
- case TYPE_KEYGUARD_SCRIM:
return false;
default:
// Hide only windows below the keyguard host window.
@@ -2701,9 +2740,34 @@
}
}
- @Override
- public WindowState getWinShowWhenLockedLw() {
- return mWinShowWhenLocked;
+ private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) {
+
+ // Keyguard visibility of window from activities are determined over activity visibility.
+ if (win.getAppToken() != null) {
+ return false;
+ }
+
+ final LayoutParams attrs = win.getAttrs();
+ final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleLw() &&
+ ((imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0
+ || !canBeHiddenByKeyguardLw(imeTarget));
+
+ // Show IME over the keyguard if the target allows it
+ boolean allowWhenLocked = (win.isInputMethodWindow() || imeTarget == this)
+ && showImeOverKeyguard;;
+
+ if (isKeyguardLocked() && isKeyguardOccluded()) {
+ // Show SHOW_WHEN_LOCKED windows if Keyguard is occluded.
+ allowWhenLocked |= (attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
+ // Show error dialogs over apps that are shown on lockscreen
+ || (attrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0;
+ }
+
+ boolean keyguardLocked = isKeyguardLocked();
+ boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER
+ && !mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID);
+ return (keyguardLocked && !allowWhenLocked && win.getDisplayId() == Display.DEFAULT_DISPLAY)
+ || hideDockDivider;
}
/** {@inheritDoc} */
@@ -2771,7 +2835,7 @@
// Assumes it's safe to show starting windows of launched apps while
// the keyguard is being hidden. This is okay because starting windows never show
// secret information.
- if (mKeyguardHidden) {
+ if (mKeyguardOccluded) {
windowFlags |= FLAG_SHOW_WHEN_LOCKED;
}
}
@@ -2904,12 +2968,6 @@
android.Manifest.permission.STATUS_BAR_SERVICE,
"PhoneWindowManager");
break;
- case TYPE_KEYGUARD_SCRIM:
- if (mKeyguardScrim != null) {
- return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
- }
- mKeyguardScrim = win;
- break;
}
return WindowManagerGlobal.ADD_OKAY;
}
@@ -2920,11 +2978,7 @@
if (mStatusBar == win) {
mStatusBar = null;
mStatusBarController.setWindow(null);
- mKeyguardDelegate.showScrim();
- } else if (mKeyguardScrim == win) {
- Log.v(TAG, "Removing keyguard scrim");
- mKeyguardScrim = null;
- } if (mNavigationBar == win) {
+ } else if (mNavigationBar == win) {
mNavigationBar = null;
mNavigationBarController.setWindow(null);
}
@@ -3081,7 +3135,7 @@
}
@Override
- public Animation createForceHideEnterAnimation(boolean onWallpaper,
+ public Animation createHiddenByKeyguardExit(boolean onWallpaper,
boolean goingToNotificationShade) {
if (goingToNotificationShade) {
return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in);
@@ -3102,7 +3156,7 @@
@Override
- public Animation createForceHideWallpaperExitAnimation(boolean goingToNotificationShade) {
+ public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) {
if (goingToNotificationShade) {
return null;
} else {
@@ -3236,8 +3290,7 @@
WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
if (attrs != null) {
final int type = attrs.type;
- if (type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
- || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
+ if (type == TYPE_KEYGUARD_DIALOG
|| (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
// the "app" is keyguard, so give it the key
return 0;
@@ -3703,12 +3756,35 @@
}
@Override
- public boolean canShowDismissingWindowWhileLockedLw() {
- // If the keyguard is trusted, it will unlock without a challenge. Therefore, if we are in
- // the process of dismissing Keyguard, we don't need to hide them as the phone will be
- // unlocked right away in any case.
- return mKeyguardDelegate != null && mKeyguardDelegate.isTrusted()
- && mCurrentlyDismissingKeyguard;
+ public void onKeyguardOccludedChangedLw(boolean occluded) {
+ if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
+ mPendingKeyguardOccluded = occluded;
+ mKeyguardOccludedChanged = true;
+ } else {
+ setKeyguardOccludedLw(occluded);
+ }
+ }
+
+ private int handleStartTransitionForKeyguardLw(int transit, @Nullable Animation anim) {
+ if (mKeyguardOccludedChanged) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded changed occluded="
+ + mPendingKeyguardOccluded);
+ mKeyguardOccludedChanged = false;
+ if (setKeyguardOccludedLw(mPendingKeyguardOccluded)) {
+ return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER;
+ }
+ }
+ if (AppTransition.isKeyguardGoingAwayTransit(transit)) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation");
+ final long startTime = anim != null
+ ? SystemClock.uptimeMillis() + anim.getStartOffset()
+ : SystemClock.uptimeMillis();
+ final long duration = anim != null
+ ? anim.getDuration()
+ : 0;
+ startKeyguardExitAnimation(startTime, duration);
+ }
+ return 0;
}
private void launchAssistLongPressAction() {
@@ -3853,7 +3929,7 @@
return;
}
- if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {
+ if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) {
// when in keyguard restricted mode, must first verify unlock
// before launching home
mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
@@ -4166,7 +4242,7 @@
boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
boolean navAllowedHidden = immersive || immersiveSticky;
navTranslucent &= !immersiveSticky; // transient trumps translucent
- boolean isKeyguardShowing = isStatusBarKeyguard() && !mHideLockScreen;
+ boolean isKeyguardShowing = isStatusBarKeyguard() && !mKeyguardOccluded;
if (!isKeyguardShowing) {
navTranslucent &= areTranslucentBarsAllowed();
}
@@ -5073,31 +5149,23 @@
mTopFullscreenOpaqueOrDimmingWindowState = null;
mTopDockedOpaqueWindowState = null;
mTopDockedOpaqueOrDimmingWindowState = null;
- mAppsToBeHidden.clear();
- mAppsThatDismissKeyguard.clear();
mForceStatusBar = false;
mForceStatusBarFromKeyguard = false;
mForceStatusBarTransparent = false;
mForcingShowNavBar = false;
mForcingShowNavBarLayer = -1;
- mHideLockScreen = false;
mAllowLockscreenWhenOn = false;
- mDismissKeyguard = DISMISS_KEYGUARD_NONE;
- mShowingLockscreen = false;
mShowingDream = false;
- mWinShowWhenLocked = null;
- mKeyguardSecure = isKeyguardSecure(mCurrentUserId);
- mKeyguardSecureIncludingHidden = mKeyguardSecure
- && (mKeyguardDelegate != null && mKeyguardDelegate.isShowing());
}
/** {@inheritDoc} */
@Override
public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
- WindowState attached) {
+ WindowState attached, WindowState imeTarget) {
if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
+ win.isVisibleOrBehindKeyguardLw());
+ applyKeyguardPolicyLw(win, imeTarget);
final int fl = PolicyControl.getWindowFlags(win, attrs);
if (mTopFullscreenOpaqueWindowState == null
&& win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD) {
@@ -5107,7 +5175,6 @@
if (attrs.type == TYPE_STATUS_BAR) {
if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
mForceStatusBarFromKeyguard = true;
- mShowingLockscreen = true;
}
if ((attrs.privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) {
mForceStatusBarTransparent = true;
@@ -5116,17 +5183,11 @@
boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
&& attrs.type < FIRST_SYSTEM_WINDOW;
- final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
- final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
final int stackId = win.getStackId();
if (mTopFullscreenOpaqueWindowState == null &&
win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
- if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
- mForceStatusBarFromKeyguard = true;
- } else {
- mForceStatusBar = true;
- }
+ mForceStatusBar = true;
}
if (attrs.type == TYPE_DREAM) {
// If the lockscreen was showing when the dream started then wait
@@ -5138,77 +5199,20 @@
}
}
- final IApplicationToken appToken = win.getAppToken();
-
// For app windows that are not attached, we decide if all windows in the app they
// represent should be hidden or if we should hide the lockscreen. For attached app
// windows we defer the decision to the window it is attached to.
if (appWindow && attached == null) {
- if (showWhenLocked) {
- // Remove any previous windows with the same appToken.
- mAppsToBeHidden.remove(appToken);
- mAppsThatDismissKeyguard.remove(appToken);
- if (mAppsToBeHidden.isEmpty()) {
- if (dismissKeyguard && !mKeyguardSecure) {
- mAppsThatDismissKeyguard.add(appToken);
- } else if (win.isDrawnLw() || win.hasAppShownWindows()) {
- mWinShowWhenLocked = win;
- mHideLockScreen = true;
- mForceStatusBarFromKeyguard = false;
- }
- }
- } else if (dismissKeyguard) {
- if (mKeyguardSecure) {
- mAppsToBeHidden.add(appToken);
- } else {
- mAppsToBeHidden.remove(appToken);
- }
- mAppsThatDismissKeyguard.add(appToken);
- } else {
- mAppsToBeHidden.add(appToken);
- }
if (isFullscreen(attrs) && StackId.normallyFullscreenWindows(stackId)) {
if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
mTopFullscreenOpaqueWindowState = win;
if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
mTopFullscreenOpaqueOrDimmingWindowState = win;
}
- if (!mAppsThatDismissKeyguard.isEmpty() &&
- mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
- if (DEBUG_LAYOUT) Slog.v(TAG,
- "Setting mDismissKeyguard true by win " + win);
- mDismissKeyguard = (mWinDismissingKeyguard == win
- && mSecureDismissingKeyguard == mKeyguardSecure)
- ? DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
- mWinDismissingKeyguard = win;
- mSecureDismissingKeyguard = mKeyguardSecure;
- mForceStatusBarFromKeyguard = mShowingLockscreen && mKeyguardSecure;
- } else if (mAppsToBeHidden.isEmpty() && showWhenLocked
- && (win.isDrawnLw() || win.hasAppShownWindows())) {
- if (DEBUG_LAYOUT) Slog.v(TAG,
- "Setting mHideLockScreen to true by win " + win);
- mHideLockScreen = true;
- mForceStatusBarFromKeyguard = false;
- }
if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
mAllowLockscreenWhenOn = true;
}
}
-
- if (!mKeyguardHidden && mWinShowWhenLocked != null &&
- mWinShowWhenLocked.getAppToken() != win.getAppToken() &&
- (attrs.flags & FLAG_SHOW_WHEN_LOCKED) == 0) {
- win.hideLw(false);
- }
- }
- } else if (mTopFullscreenOpaqueWindowState == null && mWinShowWhenLocked == null) {
- // No TopFullscreenOpaqueWindow is showing, but we found a SHOW_WHEN_LOCKED window
- // that is being hidden in an animation - keep the
- // keyguard hidden until the new window shows up and
- // we know whether to show the keyguard or not.
- if (win.isAnimatingLw() && appWindow && showWhenLocked && mKeyguardHidden) {
- mHideLockScreen = true;
- mWinShowWhenLocked = win;
}
}
@@ -5255,6 +5259,16 @@
}
}
+ private void applyKeyguardPolicyLw(WindowState win, WindowState imeTarget) {
+ if (canBeHiddenByKeyguardLw(win)) {
+ if (shouldBeHiddenByKeyguard(win, imeTarget)) {
+ win.hideLw(false /* doAnimation */);
+ } else {
+ win.showLw(false /* doAnimation */);
+ }
+ }
+ }
+
private boolean isFullscreen(WindowManager.LayoutParams attrs) {
return attrs.x == 0 && attrs.y == 0
&& attrs.width == WindowManager.LayoutParams.MATCH_PARENT
@@ -5264,17 +5278,6 @@
/** {@inheritDoc} */
@Override
public int finishPostLayoutPolicyLw() {
- if (mWinShowWhenLocked != null && mTopFullscreenOpaqueWindowState != null &&
- mWinShowWhenLocked.getAppToken() != mTopFullscreenOpaqueWindowState.getAppToken()
- && isKeyguardLocked()) {
- // A dialog is dismissing the keyguard. Put the wallpaper behind it and hide the
- // fullscreen window.
- // TODO: Make sure FLAG_SHOW_WALLPAPER is restored when dialog is dismissed. Or not.
- mWinShowWhenLocked.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
- mTopFullscreenOpaqueWindowState.hideLw(false);
- mTopFullscreenOpaqueWindowState = mWinShowWhenLocked;
- }
-
int changes = 0;
boolean topIsFullscreen = false;
@@ -5287,7 +5290,7 @@
// started while the lockscreen was showing and remember this state
// while the dream is showing.
if (!mShowingDream) {
- mDreamingLockscreen = mShowingLockscreen;
+ mDreamingLockscreen = isKeyguardShowingAndNotOccluded();
if (mDreamingSleepTokenNeeded) {
mDreamingSleepTokenNeeded = false;
mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 0, 1).sendToTarget();
@@ -5378,79 +5381,17 @@
mTopIsFullscreen = topIsFullscreen;
}
- // Hide the key guard if a visible window explicitly specifies that it wants to be
- // displayed when the screen is locked.
- if (mKeyguardDelegate != null && mStatusBar != null) {
- if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
- + mHideLockScreen);
- if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !mKeyguardSecure) {
- mKeyguardHidden = true;
- if (setKeyguardOccludedLw(true)) {
- changes |= FINISH_LAYOUT_REDO_LAYOUT
- | FINISH_LAYOUT_REDO_CONFIG
- | FINISH_LAYOUT_REDO_WALLPAPER;
- }
- if (mKeyguardDelegate.isShowing()) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mKeyguardDelegate.keyguardDone(false, false);
- }
- });
- }
- } else if (mHideLockScreen) {
- mKeyguardHidden = true;
- mWinDismissingKeyguard = null;
- if (setKeyguardOccludedLw(true)) {
- changes |= FINISH_LAYOUT_REDO_LAYOUT
- | FINISH_LAYOUT_REDO_CONFIG
- | FINISH_LAYOUT_REDO_WALLPAPER;
- }
- } else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) {
- mKeyguardHidden = false;
- boolean dismissKeyguard = false;
- final boolean trusted = mKeyguardDelegate.isTrusted();
- if (mDismissKeyguard == DISMISS_KEYGUARD_START) {
- final boolean willDismiss = trusted && mKeyguardOccluded
- && mKeyguardDelegate != null && mKeyguardDelegate.isShowing();
- if (willDismiss) {
- mCurrentlyDismissingKeyguard = true;
- }
- dismissKeyguard = true;
- }
-
- // If we are currently dismissing Keyguard, there is no need to unocclude it.
- if (!mCurrentlyDismissingKeyguard) {
- if (setKeyguardOccludedLw(false)) {
- changes |= FINISH_LAYOUT_REDO_LAYOUT
- | FINISH_LAYOUT_REDO_CONFIG
- | FINISH_LAYOUT_REDO_WALLPAPER;
- }
- }
-
- if (dismissKeyguard) {
- // Only launch the next keyguard unlock window once per window.
- mHandler.post(() -> mKeyguardDelegate.dismiss(
- trusted /* allowWhileOccluded */));
- }
- } else {
- mWinDismissingKeyguard = null;
- mSecureDismissingKeyguard = false;
- mKeyguardHidden = false;
- if (setKeyguardOccludedLw(false)) {
- changes |= FINISH_LAYOUT_REDO_LAYOUT
- | FINISH_LAYOUT_REDO_CONFIG
- | FINISH_LAYOUT_REDO_WALLPAPER;
- }
- }
- }
-
if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) {
// If the navigation bar has been hidden or shown, we need to do another
// layout pass to update that window.
changes |= FINISH_LAYOUT_REDO_LAYOUT;
}
+ if (mShowingDream != mLastShowingDream) {
+ mLastShowingDream = mShowingDream;
+ mWindowManagerFuncs.notifyShowingDreamChanged();
+ }
+
// update since mAllowLockscreenWhenOn might have changed
updateLockScreenTimeout();
return changes;
@@ -5462,6 +5403,7 @@
* @return Whether the flags have changed and we have to redo the layout.
*/
private boolean setKeyguardOccludedLw(boolean isOccluded) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded);
boolean wasOccluded = mKeyguardOccluded;
boolean showing = mKeyguardDelegate.isShowing();
if (wasOccluded && !isOccluded && showing) {
@@ -5471,9 +5413,6 @@
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;
@@ -5490,14 +5429,6 @@
}
}
- private void onKeyguardShowingStateChanged(boolean showing) {
- if (!showing) {
- synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
- mCurrentlyDismissingKeyguard = false;
- }
- }
- }
-
private boolean isStatusBarKeyguard() {
return mStatusBar != null
&& (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
@@ -5505,7 +5436,7 @@
@Override
public boolean allowAppAnimationsLw() {
- if (isStatusBarKeyguard() || mShowingDream) {
+ if (mShowingDream) {
// If keyguard or dreams is currently visible, no reason to animate behind it.
return false;
}
@@ -6657,6 +6588,12 @@
return mKeyguardDelegate.isShowing() && !mKeyguardOccluded;
}
+ @Override
+ public boolean isKeyguardTrustedLw() {
+ if (mKeyguardDelegate == null) return false;
+ return mKeyguardDelegate.isTrusted();
+ }
+
/** {@inheritDoc} */
@Override
public boolean isKeyguardLocked() {
@@ -6672,8 +6609,9 @@
/** {@inheritDoc} */
@Override
- public boolean isKeyguardShowingOrOccluded() {
- return mKeyguardDelegate == null ? false : mKeyguardDelegate.isShowing();
+ public boolean isKeyguardOccluded() {
+ if (mKeyguardDelegate == null) return false;
+ return mKeyguardOccluded;
}
/** {@inheritDoc} */
@@ -6687,25 +6625,9 @@
public void dismissKeyguardLw() {
if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw");
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- // ask the keyguard to prompt the user to authenticate if necessary
- mKeyguardDelegate.dismiss(false /* allowWhileOccluded */);
- }
- });
- }
- }
- @Override
- public void notifyActivityDrawnForKeyguardLw() {
- if (mKeyguardDelegate != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mKeyguardDelegate.onActivityDrawn();
- }
- });
+ // ask the keyguard to prompt the user to authenticate if necessary
+ mKeyguardDelegate.dismiss(true /* allowWhileOccluded */);
}
}
@@ -6717,6 +6639,11 @@
}
@Override
+ public boolean isShowingDreamLw() {
+ return mShowingDream;
+ }
+
+ @Override
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
if (mKeyguardDelegate != null) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation");
@@ -7028,8 +6955,7 @@
/** {@inheritDoc} */
@Override
public void systemReady() {
- mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
- this::onKeyguardShowingStateChanged);
+ mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
mKeyguardDelegate.onSystemReady();
readCameraLensCoverState();
@@ -7576,7 +7502,7 @@
}
}
final WindowState win = winCandidate;
- if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mHideLockScreen == true) {
+ if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mKeyguardOccluded) {
// We are updating at a point where the keyguard has gotten
// focus, but we were last in a state where the top window is
// hiding it. This is probably because the keyguard as been
@@ -7633,7 +7559,7 @@
}
private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) {
- WindowState statusColorWin = isStatusBarKeyguard() && !mHideLockScreen
+ WindowState statusColorWin = isStatusBarKeyguard() && !mKeyguardOccluded
? mStatusBar
: opaqueOrDimming;
@@ -7674,7 +7600,7 @@
final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard;
// apply translucent bar vis flags
- WindowState fullscreenTransWin = isStatusBarKeyguard() && !mHideLockScreen
+ WindowState fullscreenTransWin = isStatusBarKeyguard() && !mKeyguardOccluded
? mStatusBar
: mTopFullscreenOpaqueWindowState;
vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
@@ -7700,7 +7626,7 @@
| View.SYSTEM_UI_FLAG_IMMERSIVE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
- if (mHideLockScreen) {
+ if (mKeyguardOccluded) {
flags |= View.STATUS_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSLUCENT;
}
vis = (vis & ~flags) | (oldVis & flags);
@@ -8069,8 +7995,7 @@
pw.print(","); pw.print(mDockBottom); pw.println(")");
pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer);
pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
- pw.print(prefix); pw.print("mShowingLockscreen="); pw.print(mShowingLockscreen);
- pw.print(" mShowingDream="); pw.print(mShowingDream);
+ pw.print(prefix); pw.print("mShowingDream="); pw.print(mShowingDream);
pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen);
pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken);
if (mLastInputMethodWindow != null) {
@@ -8098,10 +8023,6 @@
pw.print(prefix); pw.print("mFocusedApp=");
pw.println(mFocusedApp);
}
- if (mWinDismissingKeyguard != null) {
- pw.print(prefix); pw.print("mWinDismissingKeyguard=");
- pw.println(mWinDismissingKeyguard);
- }
if (mTopFullscreenOpaqueWindowState != null) {
pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState=");
pw.println(mTopFullscreenOpaqueWindowState);
@@ -8116,14 +8037,13 @@
pw.println(mForcingShowNavBarLayer);
}
pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen);
- pw.print(" mHideLockScreen="); pw.println(mHideLockScreen);
+ pw.print(" mKeyguardOccluded="); pw.println(mKeyguardOccluded);
+ pw.print(" mKeyguardOccludedChanged="); pw.println(mKeyguardOccludedChanged);
+ pw.print(" mPendingKeyguardOccluded="); pw.println(mPendingKeyguardOccluded);
pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar);
pw.print(" mForceStatusBarFromKeyguard=");
pw.println(mForceStatusBarFromKeyguard);
- pw.print(prefix); pw.print("mDismissKeyguard="); pw.print(mDismissKeyguard);
- pw.print(" mCurrentlyDismissingKeyguard="); pw.println(mCurrentlyDismissingKeyguard);
- pw.print(" mWinDismissingKeyguard="); pw.print(mWinDismissingKeyguard);
- pw.print(" mHomePressed="); pw.println(mHomePressed);
+ pw.print(prefix); pw.print("mHomePressed="); pw.println(mHomePressed);
pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java
index 1dbc44e..7d67b60 100644
--- a/services/core/java/com/android/server/policy/StatusBarController.java
+++ b/services/core/java/com/android/server/policy/StatusBarController.java
@@ -56,8 +56,8 @@
}
@Override
- public void onAppTransitionStartingLocked(IBinder openToken, IBinder closeToken,
- final Animation openAnimation, final Animation closeAnimation) {
+ public int onAppTransitionStartingLocked(int transit, IBinder openToken,
+ IBinder closeToken, final Animation openAnimation, final Animation closeAnimation) {
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -71,10 +71,11 @@
}
}
});
+ return 0;
}
@Override
- public void onAppTransitionCancelledLocked() {
+ public void onAppTransitionCancelledLocked(int transit) {
mHandler.post(new Runnable() {
@Override
public void run() {
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 10c237f..28f36f7 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -1,12 +1,13 @@
package com.android.server.policy.keyguard;
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerNative;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.content.pm.ActivityInfo;
import android.content.res.Resources;
-import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -15,15 +16,13 @@
import android.util.Log;
import android.util.Slog;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
import android.view.WindowManagerPolicy.OnKeyguardExitResult;
import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
+import com.android.server.LocalServices;
import com.android.server.UiThread;
-import com.android.server.policy.keyguard.KeyguardStateMonitor.OnShowingStateChangedCallback;
import java.io.PrintWriter;
@@ -46,23 +45,13 @@
protected KeyguardServiceWrapper mKeyguardService;
private final Context mContext;
- private final View mScrim; // shown if keyguard crashes
- private final Handler mScrimHandler;
+ private final Handler mHandler;
private final KeyguardState mKeyguardState = new KeyguardState();
private DrawnListener mDrawnListenerWhenConnect;
- private final OnShowingStateChangedCallback mShowingStateChangedCallback;
private static final class KeyguardState {
KeyguardState() {
- // Assume keyguard is showing and secure until we know for sure. This is here in
- // the event something checks before the service is actually started.
- // KeyguardService itself should default to this state until the real state is known.
- showing = true;
- showingAndNotOccluded = true;
- secure = true;
- deviceHasKeyguard = true;
- enabled = true;
- currentUser = UserHandle.USER_NULL;
+ reset();
}
boolean showing;
boolean showingAndNotOccluded;
@@ -78,6 +67,18 @@
public boolean bootCompleted;
public int screenState;
public int interactiveState;
+
+ private void reset() {
+ // Assume keyguard is showing and secure until we know for sure. This is here in
+ // the event something checks before the service is actually started.
+ // KeyguardService itself should default to this state until the real state is known.
+ showing = true;
+ showingAndNotOccluded = true;
+ secure = true;
+ deviceHasKeyguard = true;
+ enabled = true;
+ currentUser = UserHandle.USER_NULL;
+ }
};
public interface DrawnListener {
@@ -98,7 +99,6 @@
if (mDrawnListener != null) {
mDrawnListener.onDrawn();
}
- hideScrim();
}
};
@@ -119,12 +119,9 @@
}
};
- public KeyguardServiceDelegate(Context context,
- OnShowingStateChangedCallback showingStateChangedCallback) {
+ public KeyguardServiceDelegate(Context context) {
mContext = context;
- mScrimHandler = UiThread.getHandler();
- mShowingStateChangedCallback = showingStateChangedCallback;
- mScrim = createScrim(context, mScrimHandler);
+ mHandler = UiThread.getHandler();
}
public void bindService(Context context) {
@@ -137,7 +134,7 @@
intent.setComponent(keyguardComponent);
if (!context.bindServiceAsUser(intent, mKeyguardConnection,
- Context.BIND_AUTO_CREATE, mScrimHandler, UserHandle.SYSTEM)) {
+ Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)) {
Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent);
mKeyguardState.showing = false;
mKeyguardState.showingAndNotOccluded = false;
@@ -147,7 +144,6 @@
// is at least self-healing but a race condition here can lead to the scrim being
// stuck on keyguard-less devices.
mKeyguardState.deviceHasKeyguard = false;
- hideScrim();
}
} else {
if (DEBUG) Log.v(TAG, "*** Keyguard started");
@@ -159,7 +155,7 @@
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
mKeyguardService = new KeyguardServiceWrapper(mContext,
- IKeyguardService.Stub.asInterface(service), mShowingStateChangedCallback);
+ IKeyguardService.Stub.asInterface(service));
if (mKeyguardState.systemIsReady) {
// If the system is ready, it means keyguard crashed and restarted.
mKeyguardService.onSystemReady();
@@ -196,8 +192,15 @@
public void onServiceDisconnected(ComponentName name) {
if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)");
mKeyguardService = null;
+ mKeyguardState.reset();
+ mHandler.post(() -> {
+ try {
+ ActivityManagerNative.getDefault().setLockScreenShown(true);
+ } catch (RemoteException e) {
+ // Local call.
+ }
+ });
}
-
};
public boolean isShowing() {
@@ -234,12 +237,6 @@
}
}
- public void keyguardDone(boolean authenticated, boolean wakeup) {
- if (mKeyguardService != null) {
- mKeyguardService.keyguardDone(authenticated, wakeup);
- }
- }
-
public void setOccluded(boolean isOccluded, boolean animate) {
if (mKeyguardService != null) {
if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate);
@@ -301,7 +298,6 @@
// This shouldn't happen, but if it does, show the scrim immediately and
// invoke the listener's callback after the service actually connects.
mDrawnListenerWhenConnect = drawnListener;
- showScrim();
}
mKeyguardState.screenState = SCREEN_STATE_TURNING_ON;
}
@@ -369,61 +365,6 @@
}
}
- private static View createScrim(Context context, Handler handler) {
- final View view = new View(context);
-
- int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
- | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
- | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
- ;
-
- final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
- final int type = WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
- final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- stretch, stretch, type, flags, PixelFormat.TRANSLUCENT);
- lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
- lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
- lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
- lp.setTitle("KeyguardScrim");
- final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- // Disable pretty much everything in statusbar until keyguard comes back and we know
- // the state of the world.
- view.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME
- | View.STATUS_BAR_DISABLE_BACK
- | View.STATUS_BAR_DISABLE_RECENT
- | View.STATUS_BAR_DISABLE_EXPAND
- | View.STATUS_BAR_DISABLE_SEARCH);
- handler.post(new Runnable() {
- @Override
- public void run() {
- wm.addView(view, lp);
- }
- });
- return view;
- }
-
- public void showScrim() {
- synchronized (mKeyguardState) {
- if (!mKeyguardState.deviceHasKeyguard) return;
- mScrimHandler.post(new Runnable() {
- @Override
- public void run() {
- mScrim.setVisibility(View.VISIBLE);
- }
- });
- }
- }
-
- public void hideScrim() {
- mScrimHandler.post(new Runnable() {
- @Override
- public void run() {
- mScrim.setVisibility(View.GONE);
- }
- });
- }
-
public void onBootCompleted() {
if (mKeyguardService != null) {
mKeyguardService.onBootCompleted();
@@ -431,12 +372,6 @@
mKeyguardState.bootCompleted = true;
}
- public void onActivityDrawn() {
- if (mKeyguardService != null) {
- mKeyguardService.onActivityDrawn();
- }
- }
-
public void dump(String prefix, PrintWriter pw) {
pw.println(prefix + TAG);
prefix += " ";
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index acc67db..b457f8d 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -26,7 +26,6 @@
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
import com.android.internal.policy.IKeyguardStateCallback;
-import com.android.server.policy.keyguard.KeyguardStateMonitor.OnShowingStateChangedCallback;
import java.io.PrintWriter;
@@ -40,11 +39,9 @@
private IKeyguardService mService;
private String TAG = "KeyguardServiceWrapper";
- public KeyguardServiceWrapper(Context context, IKeyguardService service,
- OnShowingStateChangedCallback showingStateChangedCallback) {
+ public KeyguardServiceWrapper(Context context, IKeyguardService service) {
mService = service;
- mKeyguardStateMonitor = new KeyguardStateMonitor(context, service,
- showingStateChangedCallback);
+ mKeyguardStateMonitor = new KeyguardStateMonitor(context, service);
}
@Override // Binder interface
@@ -57,15 +54,6 @@
}
@Override // Binder interface
- public void keyguardDone(boolean authenticated, boolean wakeup) {
- try {
- mService.keyguardDone(authenticated, wakeup);
- } catch (RemoteException e) {
- Slog.w(TAG , "Remote Exception", e);
- }
- }
-
- @Override // Binder interface
public void setOccluded(boolean isOccluded, boolean animate) {
try {
mService.setOccluded(isOccluded, animate);
@@ -229,15 +217,6 @@
}
@Override // Binder interface
- public void onActivityDrawn() {
- try {
- mService.onActivityDrawn();
- } catch (RemoteException e) {
- Slog.w(TAG , "Remote Exception", e);
- }
- }
-
- @Override // Binder interface
public IBinder asBinder() {
return mService.asBinder();
}
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index 712b625..f19f0aa 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -49,13 +49,11 @@
private int mCurrentUserId;
private final LockPatternUtils mLockPatternUtils;
- private final OnShowingStateChangedCallback mOnShowingStateChangedCallback;
- public KeyguardStateMonitor(Context context, IKeyguardService service,
- OnShowingStateChangedCallback showingStateChangedCallback) {
+ public KeyguardStateMonitor(Context context, IKeyguardService service) {
mLockPatternUtils = new LockPatternUtils(context);
mCurrentUserId = ActivityManager.getCurrentUser();
- mOnShowingStateChangedCallback = showingStateChangedCallback;
+
try {
service.addStateMonitorCallback(this);
} catch (RemoteException e) {
@@ -86,7 +84,6 @@
@Override // Binder interface
public void onShowingStateChanged(boolean showing) {
mIsShowing = showing;
- mOnShowingStateChangedCallback.onShowingStateChanged(showing);
}
@Override // Binder interface
@@ -126,8 +123,4 @@
pw.println(prefix + "mTrusted=" + mTrusted);
pw.println(prefix + "mCurrentUserId=" + mCurrentUserId);
}
-
- public interface OnShowingStateChangedCallback {
- void onShowingStateChanged(boolean showing);
- }
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index bde65ed..670b9cc 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1283,8 +1283,7 @@
}
private static boolean isReportedWindowType(int windowType) {
- return (windowType != WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
- && windowType != WindowManager.LayoutParams.TYPE_WALLPAPER
+ return (windowType != WindowManager.LayoutParams.TYPE_WALLPAPER
&& windowType != WindowManager.LayoutParams.TYPE_BOOT_PROGRESS
&& windowType != WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY
&& windowType != WindowManager.LayoutParams.TYPE_DRAG
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index cd46165..862c145 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -135,6 +135,21 @@
public static final int TRANSIT_ACTIVITY_RELAUNCH = 18;
/** A task is being docked from recents. */
public static final int TRANSIT_DOCK_TASK_FROM_RECENTS = 19;
+ /** Keyguard is going away */
+ public static final int TRANSIT_KEYGUARD_GOING_AWAY = 20;
+ /** Keyguard is going away with showing an activity behind that requests wallpaper */
+ public static final int TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21;
+ /** Keyguard is being occluded */
+ public static final int TRANSIT_KEYGUARD_OCCLUDE = 22;
+ /** Keyguard is being unoccluded */
+ public static final int TRANSIT_KEYGUARD_UNOCCLUDE = 23;
+
+ /** Transition flag: Keyguard is going away, but keeping the notification shade open */
+ public static final int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE = 0x1;
+ /** Transition flag: Keyguard is going away, but doesn't want an animation for it */
+ public static final int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION = 0x2;
+ /** Transition flag: Keyguard is going away while it was showing the system wallpaper. */
+ public static final int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER = 0x4;
/** Fraction of animation at which the recents thumbnail stays completely transparent */
private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.5f;
@@ -162,6 +177,7 @@
private final WindowManagerService mService;
private int mNextAppTransition = TRANSIT_UNSET;
+ private int mNextAppTransitionFlags = 0;
private int mLastUsedAppTransition = TRANSIT_UNSET;
private String mLastOpeningApp;
private String mLastClosingApp;
@@ -286,8 +302,9 @@
return mNextAppTransition;
}
- private void setAppTransition(int transit) {
+ private void setAppTransition(int transit, int flags) {
mNextAppTransition = transit;
+ mNextAppTransitionFlags |= flags;
setLastAppTransition(TRANSIT_UNSET, null, null);
}
@@ -372,27 +389,33 @@
return false;
}
- void goodToGo(AppWindowAnimator topOpeningAppAnimator, AppWindowAnimator topClosingAppAnimator,
- ArraySet<AppWindowToken> openingApps, ArraySet<AppWindowToken> closingApps) {
- int appTransition = mNextAppTransition;
+ /**
+ * @return bit-map of WindowManagerPolicy#FINISH_LAYOUT_REDO_* to indicate whether another
+ * layout pass needs to be done
+ */
+ int goodToGo(int transit, AppWindowAnimator topOpeningAppAnimator,
+ AppWindowAnimator topClosingAppAnimator, ArraySet<AppWindowToken> openingApps,
+ ArraySet<AppWindowToken> closingApps) {
mNextAppTransition = TRANSIT_UNSET;
+ mNextAppTransitionFlags = 0;
mAppTransitionState = APP_STATE_RUNNING;
- notifyAppTransitionStartingLocked(
+ int redoLayout = notifyAppTransitionStartingLocked(transit,
topOpeningAppAnimator != null ? topOpeningAppAnimator.mAppToken.token : null,
topClosingAppAnimator != null ? topClosingAppAnimator.mAppToken.token : null,
topOpeningAppAnimator != null ? topOpeningAppAnimator.animation : null,
topClosingAppAnimator != null ? topClosingAppAnimator.animation : null);
mService.getDefaultDisplayContentLocked().getDockedDividerController()
- .notifyAppTransitionStarting(openingApps, appTransition);
+ .notifyAppTransitionStarting(openingApps, transit);
// Prolong the start for the transition when docking a task from recents, unless recents
// ended it already then we don't need to wait.
- if (mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS && !mProlongedAnimationsEnded) {
+ if (transit == TRANSIT_DOCK_TASK_FROM_RECENTS && !mProlongedAnimationsEnded) {
for (int i = openingApps.size() - 1; i >= 0; i--) {
final AppWindowAnimator appAnimator = openingApps.valueAt(i).mAppAnimator;
appAnimator.startProlongAnimation(PROLONG_ANIMATION_AT_START);
}
}
+ return redoLayout;
}
/**
@@ -413,10 +436,11 @@
}
void freeze() {
- setAppTransition(AppTransition.TRANSIT_UNSET);
+ final int transit = mNextAppTransition;
+ setAppTransition(AppTransition.TRANSIT_UNSET, 0 /* flags */);
clear();
setReady();
- notifyAppTransitionCancelledLocked();
+ notifyAppTransitionCancelledLocked(transit);
}
void registerListenerLocked(AppTransitionListener listener) {
@@ -435,18 +459,20 @@
}
}
- private void notifyAppTransitionCancelledLocked() {
+ private void notifyAppTransitionCancelledLocked(int transit) {
for (int i = 0; i < mListeners.size(); i++) {
- mListeners.get(i).onAppTransitionCancelledLocked();
+ mListeners.get(i).onAppTransitionCancelledLocked(transit);
}
}
- private void notifyAppTransitionStartingLocked(IBinder openToken,
+ private int notifyAppTransitionStartingLocked(int transit, IBinder openToken,
IBinder closeToken, Animation openAnimation, Animation closeAnimation) {
+ int redoLayout = 0;
for (int i = 0; i < mListeners.size(); i++) {
- mListeners.get(i).onAppTransitionStartingLocked(openToken, closeToken, openAnimation,
- closeAnimation);
+ redoLayout |= mListeners.get(i).onAppTransitionStartingLocked(transit, openToken,
+ closeToken, openAnimation, closeAnimation);
}
+ return redoLayout;
}
private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
@@ -1406,7 +1432,8 @@
boolean canSkipFirstFrame() {
return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM
&& mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE
- && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL;
+ && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL
+ && mNextAppTransition != TRANSIT_KEYGUARD_GOING_AWAY;
}
/**
@@ -1435,7 +1462,13 @@
@Nullable Rect surfaceInsets, boolean isVoiceInteraction, boolean freeform,
int taskId) {
Animation a;
- if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
+ if (isKeyguardGoingAwayTransit(transit) && enter) {
+ a = loadKeyguardExitAnimation(transit);
+ } else if (transit == TRANSIT_KEYGUARD_OCCLUDE) {
+ a = null;
+ } else if (transit == TRANSIT_KEYGUARD_UNOCCLUDE && !enter) {
+ a = loadAnimationRes(lp, com.android.internal.R.anim.wallpaper_open_exit);
+ } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
|| transit == TRANSIT_TASK_OPEN
|| transit == TRANSIT_TASK_TO_FRONT)) {
a = loadAnimationRes(lp, enter
@@ -1590,14 +1623,30 @@
return a;
}
+ private Animation loadKeyguardExitAnimation(int transit) {
+ if ((mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) != 0) {
+ return null;
+ }
+ final boolean toShade =
+ (mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0;
+ return mService.mPolicy.createHiddenByKeyguardExit(
+ transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER, toShade);
+ }
+
int getAppStackClipMode() {
return mNextAppTransition == TRANSIT_ACTIVITY_RELAUNCH
|| mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS
+ || mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY
+ || mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER
|| mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL
? STACK_CLIP_NONE
: STACK_CLIP_AFTER_ANIM;
}
+ public int getTransitFlags() {
+ return mNextAppTransitionFlags;
+ }
+
void postAnimationCallback() {
if (mNextAppTransitionCallback != null) {
mService.mH.sendMessage(mService.mH.obtainMessage(H.DO_ANIMATION_CALLBACK,
@@ -1819,6 +1868,18 @@
case TRANSIT_DOCK_TASK_FROM_RECENTS: {
return "TRANSIT_DOCK_TASK_FROM_RECENTS";
}
+ case TRANSIT_KEYGUARD_GOING_AWAY: {
+ return "TRANSIT_KEYGUARD_GOING_AWAY";
+ }
+ case TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER: {
+ return "TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER";
+ }
+ case TRANSIT_KEYGUARD_OCCLUDE: {
+ return "TRANSIT_KEYGUARD_OCCLUDE";
+ }
+ case TRANSIT_KEYGUARD_UNOCCLUDE: {
+ return "TRANSIT_KEYGUARD_UNOCCLUDE";
+ }
default: {
return "<UNKNOWN>";
}
@@ -1933,22 +1994,24 @@
* @return true if transition is not running and should not be skipped, false if transition is
* already running
*/
- boolean prepareAppTransitionLocked(int transit, boolean alwaysKeepCurrent) {
+ boolean prepareAppTransitionLocked(int transit, boolean alwaysKeepCurrent, int flags,
+ boolean forceOverride) {
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:"
+ " transit=" + appTransitionToString(transit)
+ " " + this
+ " alwaysKeepCurrent=" + alwaysKeepCurrent
+ " Callers=" + Debug.getCallers(3));
- if (!isTransitionSet() || mNextAppTransition == TRANSIT_NONE) {
- setAppTransition(transit);
+ if (forceOverride || isKeyguardTransit(transit) || !isTransitionSet()
+ || mNextAppTransition == TRANSIT_NONE) {
+ setAppTransition(transit, flags);
} else if (!alwaysKeepCurrent) {
if (transit == TRANSIT_TASK_OPEN && isTransitionEqual(TRANSIT_TASK_CLOSE)) {
// Opening a new task always supersedes a close for the anim.
- setAppTransition(transit);
+ setAppTransition(transit, flags);
} else if (transit == TRANSIT_ACTIVITY_OPEN
&& isTransitionEqual(TRANSIT_ACTIVITY_CLOSE)) {
// Opening a new activity always supersedes a close for the anim.
- setAppTransition(transit);
+ setAppTransition(transit, flags);
}
}
boolean prepared = prepare();
@@ -1960,6 +2023,20 @@
}
/**
+ * @return true if {@param transit} is representing a transition in which Keyguard is going
+ * away, false otherwise
+ */
+ public static boolean isKeyguardGoingAwayTransit(int transit) {
+ return transit == TRANSIT_KEYGUARD_GOING_AWAY
+ || transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
+ }
+
+ private static boolean isKeyguardTransit(int transit) {
+ return isKeyguardGoingAwayTransit(transit) || transit == TRANSIT_KEYGUARD_OCCLUDE
+ || transit == TRANSIT_KEYGUARD_UNOCCLUDE;
+ }
+
+ /**
* @return whether the specified {@param uiMode} is the TV mode.
*/
private boolean isTvUiMode(int uiMode) {
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index e774259..e1b598a 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -17,6 +17,8 @@
package com.android.server.wm;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+
+import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -95,6 +97,8 @@
// that if recents doesn't tell us to remove the prolonged animation, we will get rid of it
// when new animation is set.
private boolean mClearProlongedAnimation;
+ private int mTransit;
+ private int mTransitFlags;
/** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<>();
@@ -114,15 +118,16 @@
mAnimator = mService.mAnimator;
}
- public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame,
- int stackClip) {
+ public void setAnimation(Animation anim, int width, int height, int parentWidth,
+ int parentHeight, boolean skipFirstFrame, int stackClip, int transit,
+ int transitFlags) {
if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
+ ": " + anim + " wxh=" + width + "x" + height
+ " hasContentToDisplay=" + mAppToken.hasContentToDisplay());
animation = anim;
animating = false;
if (!anim.isInitialized()) {
- anim.initialize(width, height, width, height);
+ anim.initialize(width, height, parentWidth, parentHeight);
}
anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
@@ -144,7 +149,9 @@
hasTransformation = true;
mStackClip = stackClip;
- this.mSkipFirstFrame = skipFirstFrame;
+ mSkipFirstFrame = skipFirstFrame;
+ mTransit = transit;
+ mTransitFlags = transitFlags;
if (!mAppToken.fillsParent()) {
anim.setBackgroundColor(0);
@@ -185,12 +192,22 @@
mAppToken.clearAllDrawn();
}
mStackClip = STACK_CLIP_BEFORE_ANIM;
+ mTransit = TRANSIT_UNSET;
+ mTransitFlags = 0;
}
public boolean isAnimating() {
return animation != null || mAppToken.inPendingTransaction;
}
+ public int getTransit() {
+ return mTransit;
+ }
+
+ int getTransitFlags() {
+ return mTransitFlags;
+ }
+
public void clearThumbnail() {
if (thumbnail != null) {
thumbnail.hide();
@@ -216,6 +233,7 @@
toAppAnimator.updateLayers();
updateLayers();
toAppAnimator.usingTransferredAnimation = true;
+ toAppAnimator.mTransit = mTransit;
}
if (transferWinAnimator != null) {
mAllAppWinAnimators.remove(transferWinAnimator);
@@ -435,6 +453,8 @@
if (animating || animation != null) {
pw.print(prefix); pw.print("animating="); pw.println(animating);
pw.print(prefix); pw.print("animation="); pw.println(animation);
+ pw.print(prefix); pw.print("mTransit="); pw.println(mTransit);
+ pw.print(prefix); pw.print("mTransitFlags="); pw.println(mTransitFlags);
}
if (hasTransformation) {
pw.print(prefix); pw.print("XForm: ");
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index e3588ff..a44c8aa 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -19,6 +19,8 @@
import static android.app.ActivityManager.StackId;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -152,6 +154,9 @@
int mRotationAnimationHint;
private int mPendingRelaunchCount;
+ private boolean mLastContainsShowWhenLockedWindow;
+ private boolean mLastContainsDismissKeyguardWindow;
+
private ArrayList<WindowSurfaceController.SurfaceControlWithBackground> mSurfaceViewBackgrounds =
new ArrayList<>();
@@ -718,6 +723,13 @@
if (gotReplacementWindow) {
mService.scheduleWindowReplacementTimeouts(this);
}
+ checkKeyguardFlagsChanged();
+ }
+
+ @Override
+ void removeChild(WindowState child) {
+ super.removeChild(child);
+ checkKeyguardFlagsChanged();
}
private boolean waitingForReplacement() {
@@ -808,21 +820,6 @@
}
}
- /**
- * See {@link WindowManagerService#overridePlayingAppAnimationsLw}
- */
- void overridePlayingAppAnimations(Animation a) {
- if (mAppAnimator.isAnimating()) {
- final WindowState win = findMainWindow();
- if (win == null) {
- return;
- }
- final int width = win.mContainingFrame.width();
- final int height = win.mContainingFrame.height();
- mAppAnimator.setAnimation(a, width, height, false, STACK_CLIP_NONE);
- }
- }
-
void resetJustMovedInStack() {
for (int i = mChildren.size() - 1; i >= 0; i--) {
(mChildren.get(i)).resetJustMovedInStack();
@@ -1224,6 +1221,35 @@
mFillsParent = fillsParent;
}
+ boolean containsDismissKeyguardWindow() {
+ for (int i = mChildren.size() - 1; i >= 0; i--) {
+ if ((mChildren.get(i).mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean containsShowWhenLockedWindow() {
+ for (int i = mChildren.size() - 1; i >= 0; i--) {
+ if ((mChildren.get(i).mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void checkKeyguardFlagsChanged() {
+ final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
+ final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
+ if (containsDismissKeyguard != mLastContainsDismissKeyguardWindow
+ || containsShowWhenLocked != mLastContainsShowWhenLockedWindow) {
+ mService.notifyKeyguardFlagsChanged(null /* callback */);
+ }
+ mLastContainsDismissKeyguardWindow = containsDismissKeyguard;
+ mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
+ }
+
@Override
void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 8db8118..1960285 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -62,31 +62,23 @@
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
-import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
-import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
-import static com.android.server.wm.WindowAnimator.KEYGUARD_ANIMATING_OUT;
-import static com.android.server.wm.WindowAnimator.KEYGUARD_ANIM_TIMEOUT_MS;
-import static com.android.server.wm.WindowAnimator.KEYGUARD_NOT_SHOWN;
-import static com.android.server.wm.WindowAnimator.KEYGUARD_SHOWN;
+
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -105,8 +97,6 @@
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
-import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
-import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
import android.annotation.NonNull;
@@ -133,8 +123,6 @@
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.WindowManagerPolicy;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.view.IInputMethodClient;
@@ -467,24 +455,7 @@
}
mService.mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
- if (policy.isKeyguardLocked()) {
- // The screen is locked and no top system window is requesting an orientation.
- // Return either the orientation of the show-when-locked app (if there is any) or
- // the orientation of the keyguard. No point in searching from the rest of apps.
- WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
- AppWindowToken appShowWhenLocked = winShowWhenLocked == null
- ? null : winShowWhenLocked.mAppToken;
- if (appShowWhenLocked != null) {
- int req = appShowWhenLocked.getOrientation();
- if (req == SCREEN_ORIENTATION_BEHIND) {
- req = mService.mLastKeyguardForcedOrientation;
- }
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Done at " + appShowWhenLocked
- + " -- show when locked, return " + req);
- return req;
- }
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
- "No one is requesting an orientation when the screen is locked");
+ if (policy.isKeyguardShowingAndNotOccluded()) {
return mService.mLastKeyguardForcedOrientation;
}
}
@@ -639,7 +610,7 @@
win.getTouchableRegion(mTmpRegion);
mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
}
- if (getDockedStackVisibleForUserLocked() != null) {
+ if (getDockedStackLocked() != null) {
mDividerControllerLocked.getTouchRegion(mTmpRect);
mTmpRegion.set(mTmpRect);
mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
@@ -991,11 +962,10 @@
/**
* Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not
- * visible, as long as it's not hidden because the current user doesn't have any tasks there.
+ * visible.
*/
- TaskStack getDockedStackVisibleForUserLocked() {
- final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
- return (stack != null && stack.isVisible(true /* ignoreKeyguard */)) ? stack : null;
+ TaskStack getDockedStackIgnoringVisibility() {
+ return mService.mStackIdToStack.get(DOCKED_STACK_ID);
}
/** Find the visible, touch-deliverable window under the given point */
@@ -2082,6 +2052,20 @@
}
}
+ /**
+ * Starts the Keyguard exit animation on all windows that don't belong to an app token.
+ */
+ void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade) {
+ final WindowManagerPolicy policy = mService.mPolicy;
+ for (int i = mWindows.size() - 1; i >= 0; i--) {
+ final WindowState window = mWindows.get(i);
+ if (window.mAppToken == null && policy.canBeHiddenByKeyguardLw(window)) {
+ window.mWinAnimator.setAnimation(
+ policy.createHiddenByKeyguardExit(onWallpaper, goingToShade));
+ }
+ }
+ }
+
boolean checkWaitingForWindows() {
boolean haveBootMsg = false;
@@ -2137,59 +2121,10 @@
}
void updateWindowsForAnimator(WindowAnimator animator) {
- final WindowManagerPolicy policy = animator.mPolicy;
- final int keyguardGoingAwayFlags = animator.mKeyguardGoingAwayFlags;
- final boolean keyguardGoingAwayToShade =
- (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0;
- final boolean keyguardGoingAwayNoAnimation =
- (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0;
- final boolean keyguardGoingAwayWithWallpaper =
- (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0;
-
- if (animator.mKeyguardGoingAway) {
- for (int i = mWindows.size() - 1; i >= 0; i--) {
- WindowState win = mWindows.get(i);
- if (!policy.isKeyguardHostWindow(win.mAttrs)) {
- continue;
- }
- final WindowStateAnimator winAnimator = win.mWinAnimator;
- if (policy.isKeyguardShowingAndNotOccluded()) {
- if (!winAnimator.mAnimating) {
- if (DEBUG_KEYGUARD) Slog.d(TAG,
- "updateWindowsForAnimator: creating delay animation");
-
- // Create a new animation to delay until keyguard is gone on its own.
- winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f);
- winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS);
- winAnimator.mAnimationIsEntrance = false;
- winAnimator.mAnimationStartTime = -1;
- winAnimator.mKeyguardGoingAwayAnimation = true;
- winAnimator.mKeyguardGoingAwayWithWallpaper
- = keyguardGoingAwayWithWallpaper;
- }
- } else {
- if (DEBUG_KEYGUARD) Slog.d(TAG,
- "updateWindowsForAnimator: StatusBar is no longer keyguard");
- animator.mKeyguardGoingAway = false;
- winAnimator.clearAnimation();
- }
- break;
- }
- }
-
- animator.mForceHiding = KEYGUARD_NOT_SHOWN;
-
- boolean wallpaperInUnForceHiding = false;
- boolean startingInUnForceHiding = false;
- ArrayList<WindowStateAnimator> unForceHiding = null;
- WindowState wallpaper = null;
final WallpaperController wallpaperController = mWallpaperController;
for (int i = mWindows.size() - 1; i >= 0; i--) {
WindowState win = mWindows.get(i);
WindowStateAnimator winAnimator = win.mWinAnimator;
- final int flags = win.mAttrs.flags;
- boolean canBeForceHidden = policy.canBeForceHidden(win, win.mAttrs);
- boolean shouldBeForceHidden = animator.shouldForceHide(win);
if (winAnimator.hasSurface()) {
final boolean wasAnimating = winAnimator.mWasAnimating;
final boolean nowAnimating = winAnimator.stepAnimationLocked(animator.mCurrentTime);
@@ -2208,129 +2143,6 @@
"updateWindowsAndWallpaperLocked 2", pendingLayoutChanges);
}
}
-
- if (policy.isForceHiding(win.mAttrs)) {
- if (!wasAnimating && nowAnimating) {
- if (DEBUG_KEYGUARD || DEBUG_ANIM || DEBUG_VISIBILITY) Slog.v(TAG,
- "Animation started that could impact force hide: " + win);
- animator.mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
- pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- if (DEBUG_LAYOUT_REPEATS) {
- mService.mWindowPlacerLocked.debugLayoutRepeats(
- "updateWindowsAndWallpaperLocked 3", pendingLayoutChanges);
- }
- mService.mFocusMayChange = true;
- } else if (animator.mKeyguardGoingAway && !nowAnimating) {
- // Timeout!!
- Slog.e(TAG, "Timeout waiting for animation to startup");
- policy.startKeyguardExitAnimation(0, 0);
- animator.mKeyguardGoingAway = false;
- }
- if (win.isReadyForDisplay()) {
- if (nowAnimating && win.mWinAnimator.mKeyguardGoingAwayAnimation) {
- animator.mForceHiding = KEYGUARD_ANIMATING_OUT;
- } else {
- animator.mForceHiding = win.isDrawnLw()
- ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;
- }
- }
- if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
- "Force hide " + animator.forceHidingToString()
- + " hasSurface=" + win.mHasSurface
- + " policyVis=" + win.mPolicyVisibility
- + " destroying=" + win.mDestroying
- + " parentHidden=" + win.isParentWindowHidden()
- + " vis=" + win.mViewVisibility
- + " hidden=" + win.mToken.hidden
- + " anim=" + win.mWinAnimator.mAnimation);
- } else if (canBeForceHidden) {
- if (shouldBeForceHidden) {
- if (!win.hideLw(false, false)) {
- // Was already hidden
- continue;
- }
- if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
- "Now policy hidden: " + win);
- } else {
- final Animation postKeyguardExitAnimation =
- animator.mPostKeyguardExitAnimation;
- boolean applyExistingExitAnimation = postKeyguardExitAnimation != null
- && !postKeyguardExitAnimation.hasEnded()
- && !winAnimator.mKeyguardGoingAwayAnimation
- && win.hasDrawnLw()
- && !win.isChildWindow()
- && !win.mIsImWindow
- && isDefaultDisplay;
-
- // If the window is already showing and we don't need to apply an existing
- // Keyguard exit animation, skip.
- if (!win.showLw(false, false) && !applyExistingExitAnimation) {
- continue;
- }
- final boolean visibleNow = win.isVisibleNow();
- if (!visibleNow) {
- // Couldn't really show, must showLw() again when win becomes visible.
- win.hideLw(false, false);
- continue;
- }
- if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
- "Now policy shown: " + win);
- if ((animator.mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
- && !win.isChildWindow()) {
- if (unForceHiding == null) {
- unForceHiding = new ArrayList<>();
- }
- unForceHiding.add(winAnimator);
- if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
- wallpaperInUnForceHiding = true;
- }
- if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
- startingInUnForceHiding = true;
- }
- } else if (applyExistingExitAnimation) {
- // We're already in the middle of an animation. Use the existing
- // animation to bring in this window.
- if (DEBUG_KEYGUARD) Slog.v(TAG,
- "Applying existing Keyguard exit animation to new window: win="
- + win);
-
- final Animation a = policy.createForceHideEnterAnimation(false,
- keyguardGoingAwayToShade);
- winAnimator.setAnimation(a, postKeyguardExitAnimation.getStartTime(),
- STACK_CLIP_BEFORE_ANIM);
- winAnimator.mKeyguardGoingAwayAnimation = true;
- winAnimator.mKeyguardGoingAwayWithWallpaper
- = keyguardGoingAwayWithWallpaper;
- }
- final WindowState currentFocus = mService.mCurrentFocus;
- if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
- // We are showing on top of the current
- // focus, so re-evaluate focus to make
- // sure it is correct.
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG,
- "updateWindowsForAnimator: setting mFocusMayChange true");
- mService.mFocusMayChange = true;
- }
- }
- if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
- animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
- pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- if (DEBUG_LAYOUT_REPEATS) {
- mService.mWindowPlacerLocked.debugLayoutRepeats(
- "updateWindowsAndWallpaperLocked 4", pendingLayoutChanges);
- }
- }
- }
- }
-
- // If the window doesn't have a surface, the only thing we care about is the correct
- // policy visibility.
- else if (canBeForceHidden) {
- if (shouldBeForceHidden) {
- win.hideLw(false, false);
- } else {
- win.showLw(false, false);
- }
}
final AppWindowToken atoken = win.mAppToken;
@@ -2355,77 +2167,7 @@
appAnimator.thumbnailLayer = winAnimator.mAnimLayer;
}
}
- if (win.mIsWallpaper) {
- wallpaper = win;
- }
} // end forall windows
-
- // If we have windows that are being shown due to them no longer being force-hidden, apply
- // the appropriate animation to them if animations are not disabled.
- if (unForceHiding != null) {
- if (!keyguardGoingAwayNoAnimation) {
- boolean first = true;
- for (int i=unForceHiding.size()-1; i>=0; i--) {
- final WindowStateAnimator winAnimator = unForceHiding.get(i);
- final Animation a = policy.createForceHideEnterAnimation(
- wallpaperInUnForceHiding && !startingInUnForceHiding,
- keyguardGoingAwayToShade);
- if (a != null) {
- if (DEBUG_KEYGUARD) Slog.v(TAG,
- "Starting keyguard exit animation on window " + winAnimator.mWin);
- winAnimator.setAnimation(a, STACK_CLIP_BEFORE_ANIM);
- winAnimator.mKeyguardGoingAwayAnimation = true;
- winAnimator.mKeyguardGoingAwayWithWallpaper
- = keyguardGoingAwayWithWallpaper;
- if (first) {
- animator.mPostKeyguardExitAnimation = a;
- animator.mPostKeyguardExitAnimation.setStartTime(animator.mCurrentTime);
- first = false;
- }
- }
- }
- } else if (animator.mKeyguardGoingAway) {
- policy.startKeyguardExitAnimation(animator.mCurrentTime, 0 /* duration */);
- animator.mKeyguardGoingAway = false;
- }
-
-
- // Wallpaper is going away in un-force-hide motion, animate it as well.
- if (!wallpaperInUnForceHiding && wallpaper != null && !keyguardGoingAwayNoAnimation) {
- if (DEBUG_KEYGUARD) Slog.d(TAG,
- "updateWindowsForAnimator: wallpaper animating away");
- final Animation a = policy.createForceHideWallpaperExitAnimation(
- keyguardGoingAwayToShade);
- if (a != null) {
- wallpaper.mWinAnimator.setAnimation(a);
- }
- }
- }
-
- if (animator.mPostKeyguardExitAnimation != null) {
- // We're in the midst of a keyguard exit animation.
- if (animator.mKeyguardGoingAway) {
- policy.startKeyguardExitAnimation(animator.mCurrentTime +
- animator.mPostKeyguardExitAnimation.getStartOffset(),
- animator.mPostKeyguardExitAnimation.getDuration());
- animator.mKeyguardGoingAway = false;
- }
- // mPostKeyguardExitAnimation might either be ended normally, cancelled, or "orphaned",
- // meaning that the window it was running on was removed. We check for hasEnded() for
- // ended normally and cancelled case, and check the time for the "orphaned" case.
- else if (animator.mPostKeyguardExitAnimation.hasEnded()
- || animator.mCurrentTime - animator.mPostKeyguardExitAnimation.getStartTime()
- > animator.mPostKeyguardExitAnimation.getDuration()) {
- // Done with the animation, reset.
- if (DEBUG_KEYGUARD) Slog.v(TAG, "Done with Keyguard exit animations.");
- animator.mPostKeyguardExitAnimation = null;
- }
- }
-
- final WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
- if (winShowWhenLocked != null) {
- animator.mLastShowWinWhenLocked = winShowWhenLocked;
- }
}
void updateWallpaperForAnimator(WindowAnimator animator) {
@@ -2591,18 +2333,12 @@
final WindowManagerPolicy policy = mService.mPolicy;
for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) {
final WindowState win = mWindows.get(winNdx);
- final boolean isForceHiding = policy.isForceHiding(win.mAttrs);
final boolean keyguard = policy.isKeyguardHostWindow(win.mAttrs);
- if (win.isVisibleLw() && (win.mAppToken != null || isForceHiding || keyguard)) {
+ if (win.isVisibleLw() && (win.mAppToken != null || keyguard)) {
win.mWinAnimator.mDrawState = DRAW_PENDING;
// Force add to mResizingWindows.
win.mLastContentInsets.set(-1, -1, -1, -1);
mService.mWaitingForDrawn.add(win);
-
- // No need to wait for the windows below Keyguard.
- if (isForceHiding) {
- return;
- }
}
}
}
@@ -2672,9 +2408,8 @@
mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
for (int i = mWindows.size() - 1; i >= 0; i--) {
final WindowState w = mWindows.get(i);
- if (w.mHasSurface) {
- mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow());
- }
+ mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(),
+ mService.mInputMethodTarget);
}
pendingLayoutChanges |= mService.mPolicy.finishPostLayoutPolicyLw();
if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
@@ -2855,7 +2590,7 @@
// Don't do layout of a window if it is not visible, or soon won't be visible, to avoid
// wasting time and funky changes while a window is animating away.
- final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
+ final boolean gone = (behindDream && mService.mPolicy.canBeHiddenByKeyguardLw(win))
|| win.isGoneForLayoutLw();
if (DEBUG_LAYOUT && !win.mLayoutAttached) {
@@ -2927,7 +2662,7 @@
// If this view is GONE, then skip it -- keep the current frame, and let the caller
// know so they can ignore it if they want. (We do the normal layout for INVISIBLE
// windows, since that means "perform layout as normal, just don't display").
- if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
+ if (attachedBehindDream && mService.mPolicy.canBeHiddenByKeyguardLw(win)) {
continue;
}
if ((win.mViewVisibility != GONE && win.mRelayoutCalled) || !win.mHaveFrame
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 530fb1b..743caf8 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -44,7 +44,6 @@
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.IDockedStackListener;
-import android.view.SurfaceControl;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
@@ -57,7 +56,6 @@
import com.android.server.wm.WindowManagerService.H;
import java.io.PrintWriter;
-import java.util.ArrayList;
/**
* Keeps information about the docked stack divider.
@@ -283,7 +281,7 @@
if (mWindow == null) {
return;
}
- TaskStack stack = mDisplayContent.mService.mStackIdToStack.get(DOCKED_STACK_ID);
+ TaskStack stack = mDisplayContent.getDockedStackIgnoringVisibility();
// If the stack is invisible, we policy force hide it in WindowAnimator.shouldForceHide
final boolean visible = stack != null;
@@ -536,7 +534,7 @@
}
private void checkMinimizeChanged(boolean animate) {
- if (mDisplayContent.getDockedStackVisibleForUserLocked() == null) {
+ if (mDisplayContent.getDockedStackIgnoringVisibility() == null) {
return;
}
final TaskStack homeStack = mDisplayContent.getHomeStack();
@@ -683,7 +681,7 @@
}
private boolean setMinimizedDockedStack(boolean minimized) {
- final TaskStack stack = mDisplayContent.getDockedStackVisibleForUserLocked();
+ final TaskStack stack = mDisplayContent.getDockedStackIgnoringVisibility();
notifyDockedStackMinimizedChanged(minimized, 0);
return stack != null && stack.setAdjustedForMinimizedDock(minimized ? 1f : 0f);
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index a28dc10..26f79a9 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -483,6 +483,7 @@
appToken.voiceInteraction);
mService.mOpeningApps.remove(appToken);
+ mService.mUnknownAppVisibilityController.appRemoved(appToken);
appToken.waitingToShow = false;
if (mService.mClosingApps.contains(appToken)) {
delayed = true;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7f543f9..b889db2 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -350,7 +350,7 @@
return mFillsParent
|| !StackId.isTaskResizeableByDockedStack(mStack.mStackId)
|| displayContent == null
- || displayContent.getDockedStackVisibleForUserLocked() != null;
+ || displayContent.getDockedStackIgnoringVisibility() != null;
}
/** Original bounds of the task if applicable, otherwise fullscreen rect. */
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 4d8f29d..fff2981 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -871,7 +871,7 @@
mAdjustImeAmount = adjustAmount;
mAdjustDividerAmount = adjustDividerAmount;
updateAdjustedBounds();
- return isVisible(true /* ignoreKeyguard */);
+ return isVisible();
} else {
return false;
}
@@ -907,7 +907,7 @@
if (minimizeAmount != mMinimizeAmount) {
mMinimizeAmount = minimizeAmount;
updateAdjustedBounds();
- return isVisible(true /* ignoreKeyguard */);
+ return isVisible();
} else {
return false;
}
@@ -1218,21 +1218,6 @@
}
}
- boolean isVisible() {
- return isVisible(false /* ignoreKeyguard */);
- }
-
- boolean isVisible(boolean ignoreKeyguard) {
- final boolean keyguardOn = mService.mPolicy.isKeyguardShowingOrOccluded()
- && !mService.mAnimator.mKeyguardGoingAway;
- if (!ignoreKeyguard && keyguardOn && !StackId.isAllowedOverLockscreen(mStackId)) {
- // The keyguard is showing and the stack shouldn't show on top of the keyguard.
- return false;
- }
-
- return super.isVisible();
- }
-
boolean hasTaskForUser(int userId) {
for (int i = mChildren.size() - 1; i >= 0; i--) {
final Task task = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
new file mode 100644
index 0000000..2f49c82
--- /dev/null
+++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.annotation.NonNull;
+import android.util.ArrayMap;
+
+import com.android.server.wm.WindowManagerService.H;
+
+import java.io.PrintWriter;
+
+/**
+ * Manages the set of {@link AppWindowToken}s for which we don't know yet whether it's visible or
+ * not. This happens when starting an activity while the lockscreen is showing. In that case, the
+ * keyguard flags an app might set influence it's visibility, so we wait until this is resolved to
+ * start the transition to avoid flickers.
+ */
+class UnknownAppVisibilityController {
+
+ /**
+ * We are currently waiting until the app is done resuming.
+ */
+ private static final int UNKNOWN_STATE_WAITING_RESUME = 1;
+
+ /**
+ * The activity has finished resuming, and we are waiting on the next relayout.
+ */
+ private static final int UNKNOWN_STATE_WAITING_RELAYOUT = 2;
+
+ /**
+ * The client called {@link Session#relayout} with the appropriate Keyguard flags and we are
+ * waiting until activity manager has updated the visibilities of all the apps.
+ */
+ private static final int UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE = 3;
+
+ // Set of apps for which we don't know yet whether it's visible or not, depending on what kind
+ // of lockscreen flags the app might set during its first relayout.
+ private final ArrayMap<AppWindowToken, Integer> mUnknownApps = new ArrayMap<>();
+
+ private final WindowManagerService mService;
+
+ UnknownAppVisibilityController(WindowManagerService service) {
+ mService = service;
+ }
+
+ boolean allResolved() {
+ return mUnknownApps.isEmpty();
+ }
+
+ void clear() {
+ mUnknownApps.clear();
+ }
+
+ String getDebugMessage() {
+ final StringBuilder builder = new StringBuilder();
+ for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
+ builder.append("app=").append(mUnknownApps.keyAt(i))
+ .append(" state=").append(mUnknownApps.valueAt(i));
+ if (i != 0) {
+ builder.append(' ');
+ }
+ }
+ return builder.toString();
+ }
+
+ void appRemoved(@NonNull AppWindowToken appWindow) {
+ mUnknownApps.remove(appWindow);
+ }
+
+ /**
+ * Notifies that {@param appWindow} has been launched behind Keyguard, and we need to wait until
+ * it is resumed and relaid out to resolve the visibility.
+ */
+ void notifyLaunched(@NonNull AppWindowToken appWindow) {
+ mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_RESUME);
+ }
+
+ /**
+ * Notifies that {@param appWindow} has finished resuming.
+ */
+ void notifyAppResumedFinished(@NonNull AppWindowToken appWindow) {
+ if (mUnknownApps.containsKey(appWindow)
+ && mUnknownApps.get(appWindow) == UNKNOWN_STATE_WAITING_RESUME) {
+ mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_RELAYOUT);
+ }
+ }
+
+ /**
+ * Notifies that {@param appWindow} has relaid out.
+ */
+ void notifyRelayouted(@NonNull AppWindowToken appWindow) {
+ if (!mUnknownApps.containsKey(appWindow)) {
+ return;
+ }
+ int state = mUnknownApps.get(appWindow);
+ if (state == UNKNOWN_STATE_WAITING_RELAYOUT) {
+ mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE);
+ mService.notifyKeyguardFlagsChanged(this::notifyVisibilitiesUpdated);
+ }
+ }
+
+ private void notifyVisibilitiesUpdated() {
+ boolean changed = false;
+ for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
+ if (mUnknownApps.valueAt(i) == UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE) {
+ mUnknownApps.removeAt(i);
+ changed = true;
+ }
+ }
+ if (changed) {
+ mService.mWindowPlacerLocked.performSurfacePlacement();
+ }
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ if (mUnknownApps.isEmpty()) {
+ return;
+ }
+ pw.println(prefix + "Unknown visibilities:");
+ for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
+ pw.println(prefix + " app=" + mUnknownApps.keyAt(i)
+ + " state=" + mUnknownApps.valueAt(i));
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index c9f1ffc..250d381 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -18,9 +18,12 @@
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
@@ -39,6 +42,7 @@
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.WindowManager;
+import android.view.animation.Animation;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -126,6 +130,16 @@
return isWallpaperVisible(mWallpaperTarget);
}
+ /**
+ * Starts {@param a} on all wallpaper windows.
+ */
+ void startWallpaperAnimation(Animation a) {
+ for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+ final WindowToken token = mWallpaperTokens.get(curTokenNdx);
+ token.startAnimation(a);
+ }
+ }
+
private boolean isWallpaperVisible(WindowState wallpaperTarget) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
+ (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
@@ -383,6 +397,7 @@
boolean inFreeformSpace = false;
boolean replacing = false;
boolean keyguardGoingAwayWithWallpaper = false;
+ boolean needsShowWhenLockedWallpaper = false;
for (int i = windows.size() - 1; i >= 0; i--) {
w = windows.get(i);
@@ -413,7 +428,19 @@
replacing |= w.mWillReplaceWindow;
keyguardGoingAwayWithWallpaper |= (w.mAppToken != null
- && w.mWinAnimator.mKeyguardGoingAwayWithWallpaper);
+ && AppTransition.isKeyguardGoingAwayTransit(
+ w.mAppToken.mAppAnimator.getTransit())
+ && (w.mAppToken.mAppAnimator.getTransitFlags()
+ & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0);
+
+ if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
+ && mService.mPolicy.isKeyguardLocked()
+ && mService.mPolicy.isKeyguardOccluded()) {
+ // The lowest show when locked window decides whether we need to put the wallpaper
+ // behind.
+ needsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)
+ || (w.mAppToken != null && !w.mAppToken.fillsParent());
+ }
final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
@@ -447,14 +474,19 @@
// appear and can determine the visibility, to avoid flickering.
result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
- } else if (keyguardGoingAwayWithWallpaper) {
- // If the app is executing an animation because the keyguard is going away (and the
- // keyguard was showing the wallpaper) keep the wallpaper during the animation so it
- // doesn't flicker out by having it be its own target.
+ } else if (keyguardGoingAwayWithWallpaper || needsShowWhenLockedWallpaper) {
+ // Keep the wallpaper during Keyguard exit but also when it's needed for a
+ // non-fullscreen show when locked activity.
result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
}
}
+ private boolean isFullscreen(WindowManager.LayoutParams attrs) {
+ return attrs.x == 0 && attrs.y == 0
+ && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
+ && attrs.height == WindowManager.LayoutParams.MATCH_PARENT;
+ }
+
/** Updates the target wallpaper if needed and returns true if an update happened. */
private boolean updateWallpaperWindowsTarget(
ReadOnlyWindowList windows, FindWallpaperTargetResult result) {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 4c62245..993a918 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -17,11 +17,7 @@
package com.android.server.wm;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -39,7 +35,6 @@
import android.view.Choreographer;
import android.view.SurfaceControl;
import android.view.WindowManagerPolicy;
-import android.view.animation.Animation;
import java.io.PrintWriter;
@@ -50,9 +45,6 @@
public class WindowAnimator {
private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowAnimator" : TAG_WM;
- /** How long to give statusbar to clear the private keyguard flag when animating out */
- static final long KEYGUARD_ANIM_TIMEOUT_MS = 1000;
-
final WindowManagerService mService;
final Context mContext;
final WindowManagerPolicy mPolicy;
@@ -86,37 +78,10 @@
boolean mInitialized = false;
- boolean mKeyguardGoingAway;
- int mKeyguardGoingAwayFlags;
- boolean mKeyguardAnimatingIn;
-
- /** Use one animation for all entering activities after keyguard is dismissed. */
- Animation mPostKeyguardExitAnimation;
-
- // forceHiding states.
- static final int KEYGUARD_NOT_SHOWN = 0;
- static final int KEYGUARD_SHOWN = 1;
- static final int KEYGUARD_ANIMATING_OUT = 2;
- int mForceHiding = KEYGUARD_NOT_SHOWN;
-
// When set to true the animator will go over all windows after an animation frame is posted and
// check if some got replaced and can be removed.
private boolean mRemoveReplacedWindows = false;
- private final AppTokenList mTmpExitingAppTokens = new AppTokenList();
-
- /** The window that was previously hiding the Keyguard. */
- WindowState mLastShowWinWhenLocked;
-
- String forceHidingToString() {
- switch (mForceHiding) {
- case KEYGUARD_NOT_SHOWN: return "KEYGUARD_NOT_SHOWN";
- case KEYGUARD_SHOWN: return "KEYGUARD_SHOWN";
- case KEYGUARD_ANIMATING_OUT:return "KEYGUARD_ANIMATING_OUT";
- default: return "KEYGUARD STATE UNKNOWN " + mForceHiding;
- }
- }
-
WindowAnimator(final WindowManagerService service) {
mService = service;
mContext = service.mContext;
@@ -153,63 +118,6 @@
mDisplayContentsAnimators.delete(displayId);
}
- /**
- * @return The window that is currently hiding the Keyguard, or if it was hiding the Keyguard,
- * and it's still animating.
- */
- private WindowState getWinShowWhenLockedOrAnimating() {
- final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
- if (winShowWhenLocked != null) {
- return winShowWhenLocked;
- }
- if (mLastShowWinWhenLocked != null && mLastShowWinWhenLocked.isOnScreen()
- && mLastShowWinWhenLocked.isAnimatingLw()
- && (mLastShowWinWhenLocked.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
- return mLastShowWinWhenLocked;
- }
- return null;
- }
-
- boolean shouldForceHide(WindowState win) {
- final WindowState imeTarget = mService.mInputMethodTarget;
- final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() &&
- ((imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0
- || !mPolicy.canBeForceHidden(imeTarget, imeTarget.mAttrs));
-
- final WindowState winShowWhenLocked = getWinShowWhenLockedOrAnimating();
- final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
- null : winShowWhenLocked.mAppToken;
-
- 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;
-
- 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 are shown on lockscreen
- || (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0;
- }
-
- // Allow showing a window that dismisses Keyguard if the policy allows it. This is used for
- // when the policy knows that the Keyguard can be dismissed without user interaction to
- // provide a smooth transition in that case.
- allowWhenLocked |= (win.mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0
- && mPolicy.canShowDismissingWindowWhileLockedLw();
-
- // Only hide windows if the keyguard is active and not animating away.
- boolean keyguardOn = mPolicy.isKeyguardShowingOrOccluded()
- && mForceHiding != KEYGUARD_ANIMATING_OUT
- && !mKeyguardAnimatingIn;
- boolean hideDockDivider = win.mAttrs.type == TYPE_DOCK_DIVIDER
- && win.getDisplayContent().getDockedStackLocked() == null;
- return keyguardOn && !allowWhenLocked && (win.getDisplayId() == DEFAULT_DISPLAY)
- || hideDockDivider;
- }
-
/** Locked on mService.mWindowMap. */
private void animateLocked(long frameTimeNs) {
if (!mInitialized) {
@@ -388,7 +296,6 @@
if (dumpAll) {
pw.print(prefix); pw.print("mAnimTransactionSequence=");
pw.print(mAnimTransactionSequence);
- pw.print(" mForceHiding="); pw.println(forceHidingToString());
pw.print(prefix); pw.print("mCurrentTime=");
pw.println(TimeUtils.formatUptime(mCurrentTime));
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index db61c3e..e30ebcb 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -413,12 +413,6 @@
}
}
- void overridePlayingAppAnimations(Animation a) {
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- mChildren.get(i).overridePlayingAppAnimations(a);
- }
- }
-
void setOrientation(int orientation) {
mOrientation = orientation;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1357c47..2fef928 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -178,10 +178,12 @@
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
@@ -218,7 +220,6 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -518,8 +519,6 @@
int mLastOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
boolean mAltOrientation = false;
- private boolean mKeyguardWaitingForActivityDrawn;
-
int mDockedStackCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
Rect mDockedStackCreateBounds;
@@ -584,6 +583,9 @@
final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<>();
final ArraySet<AppWindowToken> mClosingApps = new ArraySet<>();
+ final UnknownAppVisibilityController mUnknownAppVisibilityController =
+ new UnknownAppVisibilityController(this);
+
boolean mIsTouchDevice;
final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
@@ -889,7 +891,7 @@
= new WindowManagerInternal.AppTransitionListener() {
@Override
- public void onAppTransitionCancelledLocked() {
+ public void onAppTransitionCancelledLocked(int transit) {
mH.sendEmptyMessage(H.NOTIFY_APP_TRANSITION_CANCELLED);
}
@@ -1926,6 +1928,10 @@
| WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
win.mLayoutNeeded = true;
}
+ if (win.mAppToken != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0
+ || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {
+ win.mAppToken.checkKeyguardFlagsChanged();
+ }
}
if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
@@ -2069,6 +2075,10 @@
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
}
+ if (win.mAppToken != null) {
+ mUnknownAppVisibilityController.notifyRelayouted(win.mAppToken);
+ }
+
win.setDisplayLayoutNeeded();
win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
configChanged = updateOrientationFromAppTokensLocked(false, displayId);
@@ -2351,8 +2361,10 @@
if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + atoken);
final int containingWidth = frame.width();
final int containingHeight = frame.height();
- atoken.mAppAnimator.setAnimation(a, containingWidth, containingHeight,
- mAppTransition.canSkipFirstFrame(), mAppTransition.getAppStackClipMode());
+ atoken.mAppAnimator.setAnimation(a, containingWidth, containingHeight, width,
+ height, mAppTransition.canSkipFirstFrame(),
+ mAppTransition.getAppStackClipMode(),
+ transit, mAppTransition.getTransitFlags());
}
} else {
atoken.mAppAnimator.clearAnimation();
@@ -2738,20 +2750,28 @@
}
}
+ @Override
+ public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
+ prepareAppTransition(transit, alwaysKeepCurrent, 0 /* flags */, false /* forceOverride */);
+ }
+
/**
* @param transit What kind of transition is happening. Use one of the constants
* AppTransition.TRANSIT_*.
* @param alwaysKeepCurrent If true and a transition is already set, new transition will NOT
* be set.
+ * @param flags Additional flags for the app transition, Use a combination of the constants
+ * AppTransition.TRANSIT_FLAG_*.
+ * @param forceOverride Always override the transit, not matter what was set previously.
*/
- @Override
- public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
+ public void prepareAppTransition(int transit, boolean alwaysKeepCurrent, int flags,
+ boolean forceOverride) {
if (!checkCallingPermission(MANAGE_APP_TOKENS, "prepareAppTransition()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized(mWindowMap) {
- boolean prepared = mAppTransition.prepareAppTransitionLocked(
- transit, alwaysKeepCurrent);
+ boolean prepared = mAppTransition.prepareAppTransitionLocked(transit, alwaysKeepCurrent,
+ flags, forceOverride);
if (prepared && okToDisplay()) {
mSkipAppTransitionAnimation = false;
}
@@ -3186,6 +3206,19 @@
}
}
+ /**
+ * Notifies that we launched an app that might be visible or not visible depending on what kind
+ * of Keyguard flags it's going to set on its windows.
+ */
+ public void notifyUnknownAppVisibilityLaunched(IBinder token) {
+ synchronized(mWindowMap) {
+ AppWindowToken appWindow = mRoot.getAppWindowToken(token);
+ if (appWindow != null) {
+ mUnknownAppVisibilityController.notifyLaunched(appWindow);
+ }
+ }
+ }
+
@Override
public void startAppFreezingScreen(IBinder token, int configChanges) {
if (!checkCallingPermission(MANAGE_APP_TOKENS, "setAppFreezingScreen()")) {
@@ -3475,8 +3508,8 @@
}
@Override
- public void overridePlayingAppAnimationsLw(Animation a) {
- getDefaultDisplayContentLocked().overridePlayingAppAnimations(a);
+ public void notifyShowingDreamChanged() {
+ notifyKeyguardFlagsChanged(null /* callback */);
}
/**
@@ -3616,6 +3649,46 @@
}
}
+ /**
+ * @return true if the activity contains windows that have
+ * {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set
+ */
+ public boolean containsShowWhenLockedWindow(IBinder token) {
+ synchronized (mWindowMap) {
+ final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
+ return wtoken != null && wtoken.containsShowWhenLockedWindow();
+ }
+ }
+
+ /**
+ * @return true if the activity contains windows that have
+ * {@link LayoutParams#FLAG_DISMISS_KEYGUARD} set
+ */
+ public boolean containsDismissKeyguardWindow(IBinder token) {
+ synchronized (mWindowMap) {
+ final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
+ return wtoken != null && wtoken.containsDismissKeyguardWindow();
+ }
+ }
+
+ /**
+ * Notifies activity manager that some Keyguard flags have changed and that it needs to
+ * reevaluate the visibilities of the activities.
+ * @param callback Runnable to be called when activity manager is done reevaluating visibilities
+ */
+ void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
+ final Runnable wrappedCallback = callback != null
+ ? () -> { synchronized (mWindowMap) { callback.run(); } }
+ : null;
+ mH.obtainMessage(H.NOTIFY_KEYGUARD_FLAGS_CHANGED, wrappedCallback).sendToTarget();
+ }
+
+ public boolean isKeyguardTrusted() {
+ synchronized (mWindowMap) {
+ return mPolicy.isKeyguardTrustedLw();
+ }
+ }
+
// -------------------------------------------------------------
// Misc IWindowSession methods
// -------------------------------------------------------------
@@ -3752,6 +3825,12 @@
}
}
+ public boolean isShowingDream() {
+ synchronized (mWindowMap) {
+ return mPolicy.isShowingDreamLw();
+ }
+ }
+
@Override
public void dismissKeyguard() {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
@@ -3765,51 +3844,11 @@
@Override
public void keyguardGoingAway(int flags) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires DISABLE_KEYGUARD permission");
- }
- if (DEBUG_KEYGUARD) Slog.d(TAG_WM,
- "keyguardGoingAway: flags=0x" + Integer.toHexString(flags));
- synchronized (mWindowMap) {
- mAnimator.mKeyguardGoingAway = true;
- mAnimator.mKeyguardGoingAwayFlags = flags;
- mWindowPlacerLocked.requestTraversal();
- }
}
- public void keyguardWaitingForActivityDrawn() {
- if (DEBUG_KEYGUARD) Slog.d(TAG_WM, "keyguardWaitingForActivityDrawn");
+ public void onKeyguardOccludedChanged(boolean occluded) {
synchronized (mWindowMap) {
- mKeyguardWaitingForActivityDrawn = true;
- }
- }
-
- public void notifyActivityDrawnForKeyguard() {
- if (DEBUG_KEYGUARD) Slog.d(TAG_WM, "notifyActivityDrawnForKeyguard: waiting="
- + mKeyguardWaitingForActivityDrawn + " Callers=" + Debug.getCallers(5));
- synchronized (mWindowMap) {
- if (mKeyguardWaitingForActivityDrawn) {
- mPolicy.notifyActivityDrawnForKeyguardLw();
- mKeyguardWaitingForActivityDrawn = false;
- }
- }
- }
-
- @Override
- public void setKeyguardAnimatingIn(boolean animating) {
- if (!checkCallingPermission(Manifest.permission.CONTROL_KEYGUARD,
- "keyguardAnimatingIn()")) {
- throw new SecurityException("Requires CONTROL_KEYGUARD permission");
- }
- synchronized (mWindowMap) {
- mAnimator.mKeyguardAnimatingIn = animating;
- }
- }
-
- public boolean isKeyguardAnimatingIn() {
- synchronized (mWindowMap) {
- return mAnimator.mKeyguardAnimatingIn;
+ mPolicy.onKeyguardOccludedChangedLw(occluded);
}
}
@@ -6014,7 +6053,7 @@
public static final int NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED = 53;
public static final int SEAMLESS_ROTATION_TIMEOUT = 54;
public static final int RESTORE_POINTER_ICON = 55;
-
+ public static final int NOTIFY_KEYGUARD_FLAGS_CHANGED = 56;
/**
* Used to denote that an integer field in a message will not be used.
@@ -6650,6 +6689,9 @@
}
}
break;
+ case NOTIFY_KEYGUARD_FLAGS_CHANGED: {
+ mAmInternal.notifyKeyguardFlagsChanged((Runnable) msg.obj);
+ }
}
if (DEBUG_WINDOW_TRACE) {
Slog.v(TAG_WM, "handleMessage: exit");
@@ -7688,6 +7730,15 @@
}
}
+ public void notifyAppResumedFinished(IBinder token) {
+ synchronized (mWindowMap) {
+ final AppWindowToken appWindow = mRoot.getAppWindowToken(token);
+ if (appWindow != null) {
+ mUnknownAppVisibilityController.notifyAppResumedFinished(appWindow);
+ }
+ }
+ }
+
@Override
public int getDockedDividerInsetsLw() {
return getDefaultDisplayContentLocked().getDockedDividerController().getContentInsets();
@@ -7878,6 +7929,7 @@
pw.println();
mInputMonitor.dump(pw, " ");
+ mUnknownAppVisibilityController.dump(pw, " ");
if (dumpAll) {
pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
@@ -8316,7 +8368,7 @@
public int getDockedStackSide() {
synchronized (mWindowMap) {
final TaskStack dockedStack = getDefaultDisplayContentLocked()
- .getDockedStackVisibleForUserLocked();
+ .getDockedStackIgnoringVisibility();
return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 51fc9f0..534a3d2 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -87,6 +87,7 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
@@ -1211,7 +1212,8 @@
return displayContent != null ? displayContent.getDisplayInfo() : null;
}
- int getDisplayId() {
+ @Override
+ public int getDisplayId() {
final DisplayContent displayContent = getDisplayContent();
if (displayContent == null) {
return -1;
@@ -2711,13 +2713,7 @@
return false;
}
- Task task = getTask();
- if (task == null || task.inHomeStack()) {
- // Don't save surfaces for home stack apps. These usually resume and draw
- // first frame very fast. Saving surfaces are mostly a waste of memory.
- return false;
- }
-
+ final Task task = getTask();
final AppWindowToken taskTop = task.getTopVisibleAppToken();
if (taskTop != null && taskTop != mAppToken) {
// Don't save if the window is not the topmost window.
@@ -3751,6 +3747,7 @@
return null;
}
+ @Override
public int getRotationAnimationHint() {
if (mAppToken != null) {
return mAppToken.mRotationAnimationHint;
@@ -3759,6 +3756,11 @@
}
}
+ @Override
+ public boolean isInputMethodWindow() {
+ return mIsImWindow;
+ }
+
// This must be called while inside a transaction.
boolean performShowLocked() {
if (isHiddenFromUserLocked()) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 2aeb50b..a428cce 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -187,9 +187,6 @@
private boolean mAnimationStartDelayed;
- boolean mKeyguardGoingAwayAnimation;
- boolean mKeyguardGoingAwayWithWallpaper;
-
/** The pixel format of the underlying SurfaceControl */
int mSurfaceFormat;
@@ -294,8 +291,6 @@
mLocalAnimating = false;
mAnimation.cancel();
mAnimation = null;
- mKeyguardGoingAwayAnimation = false;
- mKeyguardGoingAwayWithWallpaper = false;
mStackClip = STACK_CLIP_BEFORE_ANIM;
}
}
@@ -451,8 +446,6 @@
+ (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
mAnimating = false;
- mKeyguardGoingAwayAnimation = false;
- mKeyguardGoingAwayWithWallpaper = false;
mLocalAnimating = false;
if (mAnimation != null) {
mAnimation.cancel();
@@ -1268,11 +1261,6 @@
return;
}
- final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
- if (w == winShowWhenLocked && mPolicy.isKeyguardShowingOrOccluded()) {
- return;
- }
-
final TaskStack stack = task.mStack;
stack.getDimBounds(mTmpStackBounds);
final Rect surfaceInsets = w.getAttrs().surfaceInsets;
@@ -1688,17 +1676,9 @@
* @return true if an animation has been loaded.
*/
boolean applyAnimationLocked(int transit, boolean isEntrance) {
- if ((mLocalAnimating && mAnimationIsEntrance == isEntrance)
- || mKeyguardGoingAwayAnimation) {
+ if (mLocalAnimating && mAnimationIsEntrance == isEntrance) {
// If we are trying to apply an animation, but already running
// an animation of the same type, then just leave that one alone.
-
- // If we are in a keyguard exit animation, and the window should animate away, modify
- // keyguard exit animation such that it also fades out.
- if (mAnimation != null && mKeyguardGoingAwayAnimation
- && transit == WindowManagerPolicy.TRANSIT_PREVIEW_DONE) {
- applyFadeoutDuringKeyguardExitAnimation();
- }
return true;
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 63820e5..f2682ba 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -11,6 +11,11 @@
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_CLOSE;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
@@ -347,13 +352,16 @@
final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
topClosingApp.mAppAnimator;
- mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
- mService.mOpeningApps, mService.mClosingApps);
+ final int flags = mService.mAppTransition.getTransitFlags();
+ int layoutRedo = mService.mAppTransition.goodToGo(transit, openingAppAnimator,
+ closingAppAnimator, mService.mOpeningApps, mService.mClosingApps);
+ handleNonAppWindowsInTransition(transit, flags);
mService.mAppTransition.postAnimationCallback();
mService.mAppTransition.clear();
mService.mOpeningApps.clear();
mService.mClosingApps.clear();
+ mService.mUnknownAppVisibilityController.clear();
// This has changed the visibility of windows, so perform
// a new layout to get them all up-to-date.
@@ -369,11 +377,10 @@
mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
true /*updateInputWindows*/);
mService.mFocusMayChange = false;
- mService.notifyActivityDrawnForKeyguard();
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
- return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
+ return layoutRedo | FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
}
private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
@@ -472,6 +479,26 @@
}
}
+ private void handleNonAppWindowsInTransition(int transit, int flags) {
+ if (transit == TRANSIT_KEYGUARD_GOING_AWAY) {
+ if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0
+ && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) == 0) {
+ Animation anim = mService.mPolicy.createKeyguardWallpaperExit(
+ (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
+ if (anim != null) {
+ mService.getDefaultDisplayContentLocked().mWallpaperController
+ .startWallpaperAnimation(anim);
+ }
+ }
+ }
+ if (transit == TRANSIT_KEYGUARD_GOING_AWAY
+ || transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER) {
+ mService.getDefaultDisplayContentLocked().startKeyguardExitOnNonAppWindows(
+ transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
+ (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
+ }
+ }
+
private boolean transitionGoodToGo(int appsCount) {
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Checking " + appsCount + " opening apps (frozen="
@@ -529,6 +556,14 @@
return false;
}
+ if (!mService.mUnknownAppVisibilityController.allResolved()) {
+ if (DEBUG_APP_TRANSITIONS) {
+ Slog.v(TAG, "unknownApps is not empty: "
+ + mService.mUnknownAppVisibilityController.getDebugMessage());
+ }
+ return false;
+ }
+
// If the wallpaper is visible, we need to check it's ready too.
boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
mWallpaperControllerLocked.wallpaperTransitionReady();
@@ -551,6 +586,7 @@
? null : wallpaperTarget;
final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
+ boolean openingCanBeWallpaperTarget = canBeWallpaperTarget(openingApps);
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"New wallpaper target=" + wallpaperTarget
+ ", oldWallpaper=" + oldWallpaper
@@ -575,6 +611,10 @@
}
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"New transit: " + AppTransition.appTransitionToString(transit));
+ } else if (openingCanBeWallpaperTarget && transit == TRANSIT_KEYGUARD_GOING_AWAY) {
+ transit = TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New transit: " + AppTransition.appTransitionToString(transit));
} else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
&& !openingApps.contains(oldWallpaper.mAppToken)
&& closingApps.contains(oldWallpaper.mAppToken)) {
@@ -595,6 +635,15 @@
return transit;
}
+ private boolean canBeWallpaperTarget(ArraySet<AppWindowToken> apps) {
+ for (int i = apps.size() - 1; i >= 0; i--) {
+ if (apps.valueAt(i).windowsCanBeWallpaperTarget()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void processApplicationsAnimatingInPlace(int transit) {
if (transit == TRANSIT_TASK_IN_PLACE) {
// Find the focused window
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 38f25e0..cf1a98a 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -16,20 +16,11 @@
package com.android.server.wm;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-import android.view.DisplayInfo;
-
-import java.io.PrintWriter;
import java.util.Comparator;
-
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
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_KEYGUARD_SCRIM;
+
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
@@ -39,6 +30,16 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.DisplayInfo;
+import android.view.animation.Animation;
+
+import java.io.PrintWriter;
+
/**
* Container of a set of related windows in the window manager. Often this is an AppWindowToken,
* which is the handle for an Activity that it uses to display windows. For nested windows, there is
@@ -337,6 +338,16 @@
}
}
+ /**
+ * Starts {@param anim} on all children.
+ */
+ void startAnimation(Animation anim) {
+ for (int ndx = mChildren.size() - 1; ndx >= 0; ndx--) {
+ final WindowState windowState = mChildren.get(ndx);
+ windowState.mWinAnimator.setAnimation(anim);
+ }
+ }
+
boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windowList,
WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible, int dw, int dh,
int wallpaperAnimLayerAdj) {
@@ -390,10 +401,8 @@
// 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)
- && !mService.isKeyguardAnimatingIn()) {
+ if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
insertionIndex = Math.min(windowList.indexOf(wallpaperTarget),
findLowestWindowOnScreen(windowList));
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
new file mode 100644
index 0000000..77f96ca
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link AppTransition}.
+ *
+ * runtest frameworks-services -c com.android.server.wm.AppTransitionTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class AppTransitionTests {
+
+ private WindowManagerService mWm;
+
+ @Before
+ public void setUp() throws Exception {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ mWm = TestWindowManagerPolicy.getWindowManagerService(context);
+ }
+
+ @Test
+ public void testKeyguardOverride() throws Exception {
+ mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+ mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+ assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mWm.mAppTransition.getAppTransition());
+ }
+
+ @Test
+ public void testForceOverride() throws Exception {
+ mWm.prepareAppTransition(TRANSIT_KEYGUARD_UNOCCLUDE, false /* alwaysKeepCurrent */);
+ mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */,
+ 0 /* flags */, true /* forceOverride */);
+ assertEquals(TRANSIT_ACTIVITY_OPEN, mWm.mAppTransition.getAppTransition());
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 03cbb43..3e7d272 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -55,7 +55,6 @@
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_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
@@ -115,11 +114,6 @@
}
@Override
- public boolean canShowDismissingWindowWhileLockedLw() {
- return false;
- }
-
- @Override
public void setInitialDisplaySize(Display display, int width, int height, int density) {
}
@@ -196,9 +190,6 @@
case TYPE_INPUT_METHOD_DIALOG:
// on-screen keyboards and other such input method user interfaces go here.
return 13;
- case TYPE_KEYGUARD_SCRIM:
- // the safety window that shows behind keyguard while keyguard is starting
- return 14;
case TYPE_STATUS_BAR_SUB_PANEL:
return 15;
case TYPE_STATUS_BAR:
@@ -299,27 +290,16 @@
}
@Override
- public boolean isForceHiding(WindowManager.LayoutParams attrs) {
- return false;
- }
-
- @Override
public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
return false;
}
@Override
- public boolean canBeForceHidden(WindowState win,
- WindowManager.LayoutParams attrs) {
+ public boolean canBeHiddenByKeyguardLw(WindowState win) {
return false;
}
@Override
- public WindowState getWinShowWhenLockedLw() {
- return null;
- }
-
- @Override
public View addStartingWindow(IBinder appToken, String packageName, int theme,
CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon,
int logo, int windowFlags, Configuration overrideConfig) {
@@ -359,13 +339,13 @@
}
@Override
- public Animation createForceHideEnterAnimation(boolean onWallpaper,
+ public Animation createHiddenByKeyguardExit(boolean onWallpaper,
boolean goingToNotificationShade) {
return null;
}
@Override
- public Animation createForceHideWallpaperExitAnimation(boolean goingToNotificationShade) {
+ public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) {
return null;
}
@@ -432,8 +412,7 @@
@Override
public void applyPostLayoutPolicyLw(WindowState win,
- WindowManager.LayoutParams attrs, WindowState attached) {
-
+ WindowManager.LayoutParams attrs, WindowState attached, WindowState imeTarget) {
}
@Override
@@ -523,7 +502,12 @@
}
@Override
- public boolean isKeyguardShowingOrOccluded() {
+ public boolean isKeyguardOccluded() {
+ return false;
+ }
+
+ @Override
+ public boolean isKeyguardTrustedLw() {
return false;
}
@@ -543,16 +527,20 @@
}
@Override
- public void notifyActivityDrawnForKeyguardLw() {
-
+ public boolean isKeyguardDrawnLw() {
+ return false;
}
@Override
- public boolean isKeyguardDrawnLw() {
+ public boolean isShowingDreamLw() {
return false;
}
@Override
+ public void onKeyguardOccludedChangedLw(boolean occluded) {
+ }
+
+ @Override
public int rotationForOrientationLw(int orientation,
int lastRotation) {
return 0;
diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
new file mode 100644
index 0000000..36bd13a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static junit.framework.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+
+import android.app.ActivityManagerInternal;
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.IApplicationToken;
+
+import com.android.server.LocalServices;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+
+/**
+ * Test class for {@link AppTransition}.
+ *
+ * runtest frameworks-services -c com.android.server.wm.UnknownVisibilityControllerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class UnknownAppVisibilityControllerTest {
+
+ private WindowManagerService mWm;
+ private @Mock ActivityManagerInternal mAm;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ final Context context = InstrumentationRegistry.getTargetContext();
+ LocalServices.addService(ActivityManagerInternal.class, mAm);
+ doAnswer((InvocationOnMock invocationOnMock) -> {
+ invocationOnMock.getArgumentAt(0, Runnable.class).run();
+ return null;
+ }).when(mAm).notifyKeyguardFlagsChanged(any());
+ mWm = TestWindowManagerPolicy.getWindowManagerService(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+ }
+
+ @Test
+ public void testFlow() throws Exception {
+ AppWindowToken token = createAppToken();
+ mWm.mUnknownAppVisibilityController.notifyLaunched(token);
+ mWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token);
+ mWm.mUnknownAppVisibilityController.notifyRelayouted(token);
+
+ // Make sure our handler processed the message.
+ Thread.sleep(100);
+ assertTrue(mWm.mUnknownAppVisibilityController.allResolved());
+ }
+
+ @Test
+ public void testMultiple() throws Exception {
+ AppWindowToken token1 = createAppToken();
+ AppWindowToken token2 = createAppToken();
+ mWm.mUnknownAppVisibilityController.notifyLaunched(token1);
+ mWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token1);
+ mWm.mUnknownAppVisibilityController.notifyLaunched(token2);
+ mWm.mUnknownAppVisibilityController.notifyRelayouted(token1);
+ mWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token2);
+ mWm.mUnknownAppVisibilityController.notifyRelayouted(token2);
+
+ // Make sure our handler processed the message.
+ Thread.sleep(100);
+ assertTrue(mWm.mUnknownAppVisibilityController.allResolved());
+ }
+
+ @Test
+ public void testClear() throws Exception {
+ AppWindowToken token = createAppToken();
+ mWm.mUnknownAppVisibilityController.notifyLaunched(token);
+ mWm.mUnknownAppVisibilityController.clear();;
+ assertTrue(mWm.mUnknownAppVisibilityController.allResolved());
+ }
+
+ @Test
+ public void testAppRemoved() throws Exception {
+ AppWindowToken token = createAppToken();
+ mWm.mUnknownAppVisibilityController.notifyLaunched(token);
+ mWm.mUnknownAppVisibilityController.appRemoved(token);
+ assertTrue(mWm.mUnknownAppVisibilityController.allResolved());
+ }
+
+ private AppWindowToken createAppToken() {
+ return new AppWindowToken(mWm, mock(IApplicationToken.class), false,
+ mWm.getDefaultDisplayContentLocked());
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 9ec546e..c86f5c3 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -524,10 +524,6 @@
}
@Override
- public void setKeyguardAnimatingIn(boolean animating) throws RemoteException {
- }
-
- @Override
public void setSwitchingUser(boolean switching) throws RemoteException {
}