summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorim Jaggi <jjaggi@google.com>2014-05-21 01:34:15 +0200
committerCraig Mautner <cmautner@google.com>2014-05-27 16:45:57 -0700
commit0d674623facfbd3e9c520d2be4ed98977b92a1a2 (patch)
treeab6c7fd7cb671b0e32da414fb0c640af20403c71
parent41b170d6066cb52bb3e396c608b01f2981b95e5d (diff)
downloadframeworks_base-0d674623facfbd3e9c520d2be4ed98977b92a1a2.zip
frameworks_base-0d674623facfbd3e9c520d2be4ed98977b92a1a2.tar.gz
frameworks_base-0d674623facfbd3e9c520d2be4ed98977b92a1a2.tar.bz2
Add methods to coordinate unlock animation.
Introduce IWindowManager.keyguardGoingAway to notify that Keyguard wants to dismiss it self. This method starts the state machine in WindowAnimator which animates in the activity behind the keyguard. Animating out the keyguard is done by the StatusBar/Keyguard software when it receives the startKeyguardExitAnimation() callback. Bug: 14118756 Change-Id: Id3b8f41189410bad808b4892fbec74245e59efce
-rw-r--r--core/java/android/view/IWindowManager.aidl1
-rw-r--r--core/java/android/view/WindowManagerPolicy.java18
-rw-r--r--core/java/com/android/internal/policy/IKeyguardService.aidl6
-rw-r--r--core/res/res/anim/lock_screen_behind_enter.xml5
-rw-r--r--core/res/res/anim/lock_screen_wallpaper_behind_enter.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java29
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java19
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java6
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowAnimator.java44
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java16
12 files changed, 146 insertions, 14 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 7d13399..0d5df99 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -120,6 +120,7 @@ interface IWindowManager
boolean isKeyguardSecure();
boolean inKeyguardRestrictedInputMode();
void dismissKeyguard();
+ void keyguardGoingAway();
void closeSystemDialogs(String reason);
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 1bb20c9..cfb40da 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -603,8 +603,15 @@ public interface WindowManagerPolicy {
* Return whether the given window should forcibly hide everything
* behind it. Typically returns true for the keyguard.
*/
- public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs);
-
+ public boolean doesForceHide(WindowManager.LayoutParams attrs);
+
+
+ /**
+ * Return whether the given window can become one that passes doesForceHide() test.
+ * 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 #doesForceHide}) should actually be hidden.
@@ -613,7 +620,7 @@ public interface WindowManagerPolicy {
* will conflict with what you set.
*/
public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs);
-
+
/**
* Called when the system would like to show a UI to indicate that an
* application is starting. You can use this to add a
@@ -1190,4 +1197,9 @@ public interface WindowManagerPolicy {
* @return True if the window is a top level one.
*/
public boolean isTopLevelWindow(int windowType);
+
+ /**
+ * Notifies the keyguard to start fading out.
+ */
+ public void startKeyguardExitAnimation(long fadeoutDuration);
}
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index b78c70f..f22800c 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -56,4 +56,10 @@ interface IKeyguardService {
oneway void dispatch(in MotionEvent event);
oneway void launchCamera();
oneway void onBootCompleted();
+
+ /**
+ * Notifies that the activity behind has now been drawn and it's safe to remove the wallpaper
+ * and keyguard flag.
+ */
+ oneway void startKeyguardExitAnimation(long fadeoutDuration);
}
diff --git a/core/res/res/anim/lock_screen_behind_enter.xml b/core/res/res/anim/lock_screen_behind_enter.xml
index cb47b3c..4a956d7 100644
--- a/core/res/res/anim/lock_screen_behind_enter.xml
+++ b/core/res/res/anim/lock_screen_behind_enter.xml
@@ -20,9 +20,8 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ff000000" android:shareInterpolator="false">
<alpha
- android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:fromAlpha="1.0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true"
android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="@android:integer/config_shortAnimTime"
- android:duration="@android:integer/config_shortAnimTime"/>
+ android:duration="0"/>
</set> \ No newline at end of file
diff --git a/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml b/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml
index c29fd1a..f7a6a65 100644
--- a/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml
+++ b/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml
@@ -23,6 +23,6 @@
android:fromAlpha="0.0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true"
android:interpolator="@interpolator/decelerate_quad"
- android:startOffset="@android:integer/config_shortAnimTime"
+ android:startOffset="@android:integer/config_mediumAnimTime"
android:duration="@android:integer/config_shortAnimTime"/>
</set>
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 41c0e78..4c7f3df 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -202,6 +202,12 @@ public class KeyguardService extends Service {
checkPermission();
mKeyguardViewMediator.onBootCompleted();
}
+
+ @Override
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ checkPermission();
+ mKeyguardViewMediator.startKeyguardExitAnimation(fadeoutDuration);
+ }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index b2872fa..7110d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -46,7 +46,8 @@ import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.view.ViewGroup;
-import android.view.WindowManager;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy;
import com.android.internal.policy.IKeyguardExitCallback;
@@ -137,6 +138,7 @@ public class KeyguardViewMediator extends SystemUI {
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;
/**
* The default amount of time we stay awake (used for all key input)
@@ -180,6 +182,9 @@ public class KeyguardViewMediator extends SystemUI {
/** 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;
+
/** UserManager for querying number of users */
private UserManager mUserManager;
@@ -440,6 +445,7 @@ public class KeyguardViewMediator extends SystemUI {
private void setup() {
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mWM = WindowManagerGlobal.getWindowManagerService();
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
mShowKeyguardWakeLock.setReferenceCounted(false);
@@ -1076,6 +1082,9 @@ public class KeyguardViewMediator extends SystemUI {
case DISMISS:
handleDismiss();
break;
+ case START_KEYGUARD_EXIT_ANIM:
+ handleStartKeyguardExitAnimation((Long) msg.obj);
+ break;
}
}
};
@@ -1207,6 +1216,19 @@ public class KeyguardViewMediator extends SystemUI {
private void handleHide() {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleHide");
+ try {
+
+ // Don't actually hide the Keyguard at the moment, wait for window manager until
+ // it tells us it's safe to do so with startKeyguardExitAnimation.
+ mWM.keyguardGoingAway();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error while calling WindowManager", e);
+ }
+ }
+ }
+
+ private void handleStartKeyguardExitAnimation(long fadeoutDuration) {
+ synchronized (KeyguardViewMediator.this) {
// only play "unlock" noises if not on a call (since the incall UI
// disables the keyguard)
@@ -1324,6 +1346,11 @@ public class KeyguardViewMediator extends SystemUI {
return mStatusBarKeyguardViewManager;
}
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM, fadeoutDuration);
+ mHandler.sendMessage(msg);
+ }
+
public ViewMediatorCallback getViewMediatorCallback() {
return mViewMediatorCallback;
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index e178773..fb02ebe 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1567,11 +1567,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
- public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
+ public boolean doesForceHide(WindowManager.LayoutParams attrs) {
return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
}
@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) {
case TYPE_STATUS_BAR:
@@ -4533,6 +4538,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ @Override
+ public void startKeyguardExitAnimation(final long fadeoutDuration) {
+ if (mKeyguardDelegate != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mKeyguardDelegate.startKeyguardExitAnimation(fadeoutDuration);
+ }
+ });
+ }
+ }
+
void sendCloseSystemWindows() {
sendCloseSystemWindows(mContext, null);
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
index 966924b..faf7020 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -274,6 +274,12 @@ public class KeyguardServiceDelegate {
mKeyguardState.currentUser = newUserId;
}
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ if (mKeyguardService != null) {
+ mKeyguardService.startKeyguardExitAnimation(fadeoutDuration);
+ }
+ }
+
private static final View createScrim(Context context) {
View view = new View(context);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
index 7cb48fa..f236ce7 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
@@ -190,6 +190,14 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ try {
+ mService.startKeyguardExitAnimation(fadeoutDuration);
+ } catch (RemoteException e) {
+ Slog.w(TAG , "Remote Exception", e);
+ }
+ }
+
public void showAssistant() {
// Not used by PhoneWindowManager
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 266527d..6fdd535 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -36,6 +36,7 @@ import android.util.TimeUtils;
import android.view.Display;
import android.view.SurfaceControl;
import android.view.WindowManagerPolicy;
+import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import com.android.server.wm.WindowManagerService.LayoutFields;
@@ -50,6 +51,9 @@ import java.util.ArrayList;
public class WindowAnimator {
private static final String TAG = "WindowAnimator";
+ /** How long to give statusbar to clear the private keyguard flag when animating out */
+ private static final long KEYGUARD_ANIM_TIMEOUT_MS = 1000;
+
final WindowManagerService mService;
final Context mContext;
final WindowManagerPolicy mPolicy;
@@ -82,6 +86,8 @@ public class WindowAnimator {
boolean mInitialized = false;
+ boolean mKeyguardGoingAway;
+
// forceHiding states.
static final int KEYGUARD_NOT_SHOWN = 0;
static final int KEYGUARD_ANIMATING_IN = 1;
@@ -213,6 +219,29 @@ public class WindowAnimator {
final WindowList windows = mService.getWindowListLocked(displayId);
ArrayList<WindowStateAnimator> unForceHiding = null;
boolean wallpaperInUnForceHiding = false;
+
+ if (mKeyguardGoingAway) {
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ WindowState win = windows.get(i);
+ if (!mPolicy.isKeyguardHostWindow(win.mAttrs)) {
+ continue;
+ }
+ final WindowStateAnimator winAnimator = win.mWinAnimator;
+ if (mPolicy.doesForceHide(win.mAttrs)) {
+ if (!winAnimator.mAnimating) {
+ // 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;
+ }
+ } else {
+ mKeyguardGoingAway = false;
+ winAnimator.clearAnimation();
+ }
+ break;
+ }
+ }
+
mForceHiding = KEYGUARD_NOT_SHOWN;
for (int i = windows.size() - 1; i >= 0; i--) {
@@ -239,7 +268,7 @@ public class WindowAnimator {
}
}
- if (mPolicy.doesForceHide(win, win.mAttrs)) {
+ if (mPolicy.doesForceHide(win.mAttrs)) {
if (!wasAnimating && nowAnimating) {
if (WindowManagerService.DEBUG_ANIM ||
WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
@@ -252,6 +281,11 @@ public class WindowAnimator {
getPendingLayoutChanges(displayId));
}
mService.mFocusMayChange = true;
+ } else if (mKeyguardGoingAway && !nowAnimating) {
+ // Timeout!!
+ Slog.e(TAG, "Timeout waiting for animation to startup");
+ mPolicy.startKeyguardExitAnimation(0);
+ mKeyguardGoingAway = false;
}
if (win.isReadyForDisplay()) {
if (nowAnimating) {
@@ -265,7 +299,7 @@ public class WindowAnimator {
}
}
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
- "Force hide " + mForceHiding
+ "Force hide " + forceHidingToString()
+ " hasSurface=" + win.mHasSurface
+ " policyVis=" + win.mPolicyVisibility
+ " destroying=" + win.mDestroying
@@ -349,12 +383,18 @@ public class WindowAnimator {
// If we have windows that are being show due to them no longer
// being force-hidden, apply the appropriate animation to them.
if (unForceHiding != null) {
+ boolean startKeyguardExit = true;
for (int i=unForceHiding.size()-1; i>=0; i--) {
Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding);
if (a != null) {
final WindowStateAnimator winAnimator = unForceHiding.get(i);
winAnimator.setAnimation(a);
winAnimator.mAnimationIsEntrance = true;
+ if (startKeyguardExit) {
+ // Do one time only.
+ mPolicy.startKeyguardExitAnimation(a.getStartOffset());
+ startKeyguardExit = false;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6fbb39d..27ab5ac 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5126,6 +5126,18 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void keyguardGoingAway() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires DISABLE_KEYGUARD permission");
+ }
+ synchronized (mWindowMap) {
+ mAnimator.mKeyguardGoingAway = true;
+ requestTraversalLocked();
+ }
+ }
+
+ @Override
public void closeSystemDialogs(String reason) {
synchronized(mWindowMap) {
final int numDisplays = mDisplayContents.size();
@@ -7148,9 +7160,7 @@ public class WindowManagerService extends IWindowManager.Stub
public static final int TAP_OUTSIDE_STACK = 31;
public static final int NOTIFY_ACTIVITY_DRAWN = 32;
- public static final int REMOVE_STARTING_TIMEOUT = 33;
-
- public static final int SHOW_DISPLAY_MASK = 34;
+ public static final int SHOW_DISPLAY_MASK = 33;
@Override
public void handleMessage(Message msg) {