Merge "split active user animation across switch."
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
index de3354a..4df434c 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
@@ -197,7 +197,7 @@
         }
 
         @Override
-        public void onUserSwitched(int userId) {
+        public void onUserSwitching(int userId) {
             if (DEBUG) Log.d(TAG, "onUserSwitched(" + userId + ")");
             if (mBiometricUnlock != null) {
                 mBiometricUnlock.stop();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index b05d111..217e5d7 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -101,9 +101,12 @@
     private boolean mSafeModeEnabled;
 
     private boolean mUserSetupCompleted;
+
     // User for whom this host view was created
     private int mUserId;
 
+    private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
+
     /*package*/ interface TransportCallback {
         void onListenerDetached();
         void onListenerAttached();
@@ -209,6 +212,12 @@
                 mCleanupAppWidgetsOnBootCompleted = false;
             }
         }
+        @Override
+        public void onUserSwitchComplete(int userId) {
+            if (mKeyguardMultiUserSelectorView != null) {
+                mKeyguardMultiUserSelectorView.finalizeActiveUserView(true);
+            }
+        }
     };
 
     private SlidingChallengeLayout mSlidingChallengeLayout;
@@ -399,6 +408,12 @@
         }
     };
 
+    public void initializeSwitchingUserState(boolean switching) {
+        if (!switching && mKeyguardMultiUserSelectorView != null) {
+            mKeyguardMultiUserSelectorView.finalizeActiveUserView(false);
+        }
+    }
+
     public void userActivity() {
         if (mViewMediatorCallback != null) {
             mViewMediatorCallback.userActivity();
@@ -1452,10 +1467,9 @@
 
         if (users.size() > 1) {
             if (multiUserView instanceof KeyguardMultiUserSelectorView) {
-                KeyguardMultiUserSelectorView multiUser =
-                        (KeyguardMultiUserSelectorView) multiUserView;
-                multiUser.setVisibility(View.VISIBLE);
-                multiUser.addUsers(users);
+                mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
+                mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
+                mKeyguardMultiUserSelectorView.addUsers(users);
                 UserSwitcherCallback callback = new UserSwitcherCallback() {
                     @Override
                     public void hideSecurityView(int duration) {
@@ -1481,7 +1495,7 @@
                         }
                     }
                 };
-                multiUser.setCallback(callback);
+                mKeyguardMultiUserSelectorView.setCallback(callback);
             } else {
                 Throwable t = new Throwable();
                 t.fillInStackTrace();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
index 7bf2bf9..9d1f041 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
@@ -69,6 +69,7 @@
     private boolean mInit = true;
     private KeyguardMultiUserSelectorView mUserSelector;
     private KeyguardCircleFramedDrawable mFramed;
+    private boolean mPressLock;
 
     public static KeyguardMultiUserAvatar fromXml(int resId, Context context,
             KeyguardMultiUserSelectorView userSelector, UserInfo info) {
@@ -212,13 +213,22 @@
 
     @Override
     public void setPressed(boolean pressed) {
-        if (!pressed || isClickable()) {
+        if (mPressLock && !pressed) {
+            return;
+        }
+
+        if (mPressLock || !pressed || isClickable()) {
             super.setPressed(pressed);
             mFramed.setPressed(pressed);
             mUserImage.invalidate();
         }
     }
 
+    public void lockPressed(boolean pressed) {
+        mPressLock = pressed;
+        setPressed(pressed);
+    }
+
     public UserInfo getUserInfo() {
         return mUserInfo;
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
index 728e87c..f9ea5bb 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
@@ -81,11 +81,28 @@
             KeyguardMultiUserAvatar uv = createAndAddUser(user);
             if (user.id == activeUser.id) {
                 mActiveUserAvatar = uv;
-                mActiveUserAvatar.setActive(true, false, null);
-            } else {
-                uv.setActive(false, false, null);
             }
+            uv.setActive(false, false, null);
         }
+        mActiveUserAvatar.lockPressed(true);
+    }
+
+    public void finalizeActiveUserView(boolean animate) {
+        if (animate) {
+            getHandler().postDelayed(new Runnable() {
+                    @Override
+                        public void run() {
+                        finalizeActiveUserNow(true);
+                    }
+                }, 500);
+        } else {
+            finalizeActiveUserNow(animate);
+        }
+    }
+
+    void finalizeActiveUserNow(boolean animate) {
+        mActiveUserAvatar.lockPressed(false);
+        mActiveUserAvatar.setActive(true, animate, null);
     }
 
     Comparator<UserInfo> mOrderAddedComparator = new Comparator<UserInfo>() {
@@ -132,25 +149,21 @@
                 // Reset the previously active user to appear inactive
                 mCallback.hideSecurityView(FADE_OUT_ANIMATION_DURATION);
                 setAllClickable(false);
+                avatar.lockPressed(true);
                 mActiveUserAvatar.setActive(false, true, new Runnable() {
                     @Override
                     public void run() {
                         mActiveUserAvatar = avatar;
-                        mActiveUserAvatar.setActive(true, true, new Runnable() {
-                            @Override
-                            public void run() {
-                                if (this.getClass().getName().contains("internal")) {
-                                    try {
-                                        ActivityManagerNative.getDefault()
-                                                .switchUser(avatar.getUserInfo().id);
-                                    } catch (RemoteException re) {
-                                        Log.e(TAG, "Couldn't switch user " + re);
-                                    }
-                                } else {
-                                    setAllClickable(true);
-                                }
+                        if (this.getClass().getName().contains("internal")) {
+                            try {
+                                ActivityManagerNative.getDefault()
+                                        .switchUser(avatar.getUserInfo().id);
+                            } catch (RemoteException re) {
+                                Log.e(TAG, "Couldn't switch user " + re);
                             }
-                        });
+                        } else {
+                            setAllClickable(true);
+                        }
                     }
                 });
             }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index ad6f55c..c9bffbe 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -79,10 +79,11 @@
     private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
     private static final int MSG_DEVICE_PROVISIONED = 308;
     private static final int MSG_DPM_STATE_CHANGED = 309;
-    private static final int MSG_USER_SWITCHED = 310;
+    private static final int MSG_USER_SWITCHING = 310;
     private static final int MSG_USER_REMOVED = 311;
     private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;
     protected static final int MSG_BOOT_COMPLETED = 313;
+    private static final int MSG_USER_SWITCH_COMPLETE = 314;
 
 
     private static KeyguardUpdateMonitor sInstance;
@@ -147,8 +148,11 @@
                 case MSG_DPM_STATE_CHANGED:
                     handleDevicePolicyManagerStateChanged();
                     break;
-                case MSG_USER_SWITCHED:
-                    handleUserSwitched(msg.arg1, (IRemoteCallback)msg.obj);
+                case MSG_USER_SWITCHING:
+                    handleUserSwitching(msg.arg1, (IRemoteCallback)msg.obj);
+                    break;
+                case MSG_USER_SWITCH_COMPLETE:
+                    handleUserSwitchComplete(msg.arg1);
                     break;
                 case MSG_USER_REMOVED:
                     handleUserRemoved(msg.arg1);
@@ -359,11 +363,13 @@
                     new IUserSwitchObserver.Stub() {
                         @Override
                         public void onUserSwitching(int newUserId, IRemoteCallback reply) {
-                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED,
+                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
                                     newUserId, 0, reply));
                         }
                         @Override
                         public void onUserSwitchComplete(int newUserId) throws RemoteException {
+                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
+                                    newUserId));
                         }
                     });
         } catch (RemoteException e) {
@@ -418,13 +424,13 @@
     }
 
     /**
-     * Handle {@link #MSG_USER_SWITCHED}
+     * Handle {@link #MSG_USER_SWITCHING}
      */
-    protected void handleUserSwitched(int userId, IRemoteCallback reply) {
+    protected void handleUserSwitching(int userId, IRemoteCallback reply) {
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
-                cb.onUserSwitched(userId);
+                cb.onUserSwitching(userId);
             }
         }
         setAlternateUnlockEnabled(false);
@@ -435,6 +441,18 @@
     }
 
     /**
+     * Handle {@link #MSG_USER_SWITCH_COMPLETE}
+     */
+    protected void handleUserSwitchComplete(int userId) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onUserSwitchComplete(userId);
+            }
+        }
+    }
+
+    /**
      * Handle {@link #MSG_BOOT_COMPLETED}
      */
     protected void handleBootCompleted() {
@@ -456,7 +474,7 @@
     }
 
     /**
-     * Handle {@link #MSG_USER_SWITCHED}
+     * Handle {@link #MSG_USER_REMOVED}
      */
     protected void handleUserRemoved(int userId) {
         for (int i = 0; i < mCallbacks.size(); i++) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
index 1ba1388..2126f06 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
@@ -85,9 +85,14 @@
     void onDevicePolicyManagerStateChanged() { }
 
     /**
-     * Called when the user changes.
+     * Called when the user change begins.
      */
-    void onUserSwitched(int userId) { }
+    void onUserSwitching(int userId) { }
+
+    /**
+     * Called when the user change is complete.
+     */
+    void onUserSwitchComplete(int userId) { }
 
     /**
      * Called when the SIM state changes.
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
index ff136b1..8562f0c 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
@@ -53,6 +53,7 @@
     private final static boolean DEBUG = KeyguardViewMediator.DEBUG;
     private static String TAG = "KeyguardViewManager";
     public static boolean USE_UPPER_CASE = true;
+    public final static String IS_SWITCHING_USER = "is_switching_user";
 
     // Timeout used for keypresses
     static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
@@ -237,6 +238,8 @@
         mKeyguardView = (KeyguardHostView) view.findViewById(R.id.keyguard_host_view);
         mKeyguardView.setLockPatternUtils(mLockPatternUtils);
         mKeyguardView.setViewMediatorCallback(mViewMediatorCallback);
+        mKeyguardView.initializeSwitchingUserState(options != null &&
+                options.getBoolean(IS_SWITCHING_USER));
 
         // HACK
         // The keyguard view will have set up window flags in onFinishInflate before we set
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 7d757ff..fef0613 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -153,6 +153,7 @@
     private StatusBarManager mStatusBarManager;
     private boolean mShowLockIcon;
     private boolean mShowingLockIcon;
+    private boolean mSwitchingUser;
 
     private boolean mSystemReady;
 
@@ -310,11 +311,12 @@
     KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
 
         @Override
-        public void onUserSwitched(int userId) {
+        public void onUserSwitching(int userId) {
             // Note that the mLockPatternUtils user has already been updated from setCurrentUser.
             // We need to force a reset of the views, since lockNow (called by
             // ActivityManagerService) will not reconstruct the keyguard if it is already showing.
             synchronized (KeyguardViewMediator.this) {
+                mSwitchingUser = true;
                 resetStateLocked(null);
                 adjustStatusBarLocked();
                 // Disable face unlock when the user switches.
@@ -323,6 +325,11 @@
         }
 
         @Override
+        public void onUserSwitchComplete(int userId) {
+            mSwitchingUser = false;
+        }
+
+        @Override
         public void onUserRemoved(int userId) {
             mLockPatternUtils.removeUser(userId);
         }
@@ -1361,6 +1368,10 @@
      * @see #RESET
      */
     private void handleReset(Bundle options) {
+        if (options == null) {
+            options = new Bundle();
+        }
+        options.putBoolean(KeyguardViewManager.IS_SWITCHING_USER, mSwitchingUser);
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleReset");
             mKeyguardViewManager.reset(options);