166b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen/* 266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * Copyright (C) 2012 The Android Open Source Project 366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * 466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * Licensed under the Apache License, Version 2.0 (the "License"); 566b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * you may not use this file except in compliance with the License. 666b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * You may obtain a copy of the License at 766b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * 866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * http://www.apache.org/licenses/LICENSE-2.0 966b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * 1066b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * Unless required by applicable law or agreed to in writing, software 1166b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * distributed under the License is distributed on an "AS IS" BASIS, 1266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * See the License for the specific language governing permissions and 1466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen * limitations under the License. 1566b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen */ 1666b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 175ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.keyguard; 1866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 1966b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.app.ActivityManagerNative; 2066b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.content.Context; 2166b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.content.pm.UserInfo; 2266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.os.RemoteException; 2366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.util.AttributeSet; 2424b351ab748cf1b2e41d106508604ba09f62d859Adam Cohenimport android.util.Log; 2519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerimport android.view.MotionEvent; 2624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohenimport android.view.View; 27022554e3da6e496524387a5d3ecc67ef9749b587Jim Millerimport android.view.ViewGroup; 2824b351ab748cf1b2e41d106508604ba09f62d859Adam Cohenimport android.widget.FrameLayout; 291254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka 3066b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport java.util.ArrayList; 3128c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wrenimport java.util.Collection; 3224b351ab748cf1b2e41d106508604ba09f62d859Adam Cohenimport java.util.Collections; 3324b351ab748cf1b2e41d106508604ba09f62d859Adam Cohenimport java.util.Comparator; 3466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 3524b351ab748cf1b2e41d106508604ba09f62d859Adam Cohenpublic class KeyguardMultiUserSelectorView extends FrameLayout implements View.OnClickListener { 3624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen private static final String TAG = "KeyguardMultiUserSelectorView"; 3724b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen 38022554e3da6e496524387a5d3ecc67ef9749b587Jim Miller private ViewGroup mUsersGrid; 3924b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen private KeyguardMultiUserAvatar mActiveUserAvatar; 40109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller private KeyguardHostView.UserSwitcherCallback mCallback; 4124b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen private static final int FADE_OUT_ANIMATION_DURATION = 100; 4266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 4366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen public KeyguardMultiUserSelectorView(Context context) { 4466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen this(context, null, 0); 4566b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } 4666b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 4766b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs) { 4866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen this(context, attrs, 0); 4966b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } 5066b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 5166b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs, int defStyle) { 5266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen super(context, attrs, defStyle); 5366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } 5466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 5566b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen protected void onFinishInflate () { 5628c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren mUsersGrid = (ViewGroup) findViewById(R.id.keyguard_users_grid); 5728c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren mUsersGrid.removeAllViews(); 5828c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren setClipChildren(false); 5928c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren setClipToPadding(false); 6028c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren 6166b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } 6266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 63109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller public void setCallback(KeyguardHostView.UserSwitcherCallback callback) { 6424b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen mCallback = callback; 6524b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen } 6666b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 6728c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren public void addUsers(Collection<UserInfo> userList) { 6824b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen UserInfo activeUser; 6966b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen try { 7024b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen activeUser = ActivityManagerNative.getDefault().getCurrentUser(); 7166b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } catch (RemoteException re) { 7224b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen activeUser = null; 7366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } 7466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 7528c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren ArrayList<UserInfo> users = new ArrayList<UserInfo>(userList); 7624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen Collections.sort(users, mOrderAddedComparator); 7724b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen 7866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen for (UserInfo user: users) { 7924b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen KeyguardMultiUserAvatar uv = createAndAddUser(user); 8024b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen if (user.id == activeUser.id) { 8124b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen mActiveUserAvatar = uv; 8266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } 83f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren uv.setActive(false, false, null); 84f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren } 85f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren mActiveUserAvatar.lockPressed(true); 86f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren } 87f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren 88f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren public void finalizeActiveUserView(boolean animate) { 89f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren if (animate) { 90f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren getHandler().postDelayed(new Runnable() { 91f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren @Override 92f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren public void run() { 93f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren finalizeActiveUserNow(true); 94f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren } 95f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren }, 500); 96f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren } else { 97f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren finalizeActiveUserNow(animate); 9866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } 9966b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } 10066b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 101f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren void finalizeActiveUserNow(boolean animate) { 102f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren mActiveUserAvatar.lockPressed(false); 103f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren mActiveUserAvatar.setActive(true, animate, null); 104f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren } 105f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren 10624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen Comparator<UserInfo> mOrderAddedComparator = new Comparator<UserInfo>() { 10724b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen @Override 10824b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen public int compare(UserInfo lhs, UserInfo rhs) { 10924b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen return (lhs.serialNumber - rhs.serialNumber); 11024b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen } 11124b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen }; 11266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen 11324b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen private KeyguardMultiUserAvatar createAndAddUser(UserInfo user) { 11466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen KeyguardMultiUserAvatar uv = KeyguardMultiUserAvatar.fromXml( 11566b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen R.layout.keyguard_multi_user_avatar, mContext, this, user); 11624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen mUsersGrid.addView(uv); 11724b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen return uv; 11824b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen } 11924b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen 12024b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen @Override 12119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller public boolean onInterceptTouchEvent(MotionEvent event) { 12219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller if(event.getActionMasked() != MotionEvent.ACTION_CANCEL && mCallback != null) { 12319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller mCallback.userActivity(); 12419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller } 12519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller return false; 12619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller } 12719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller 128f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren private void setAllClickable(boolean clickable) 129f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren { 130f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren for(int i = 0; i < mUsersGrid.getChildCount(); i++) { 131f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren View v = mUsersGrid.getChildAt(i); 132f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren v.setClickable(clickable); 133f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren v.setPressed(false); 134f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren } 135f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren } 136f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren 13719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller @Override 13824b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen public void onClick(View v) { 13924b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen if (!(v instanceof KeyguardMultiUserAvatar)) return; 14024b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen final KeyguardMultiUserAvatar avatar = (KeyguardMultiUserAvatar) v; 141f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren if (avatar.isClickable()) { // catch race conditions 142f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren if (mActiveUserAvatar == avatar) { 143f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren // If they click the currently active user, show the unlock hint 144f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren mCallback.showUnlockHint(); 145f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren return; 146f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren } else { 147f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren // Reset the previously active user to appear inactive 148f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren mCallback.hideSecurityView(FADE_OUT_ANIMATION_DURATION); 149f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren setAllClickable(false); 150f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren avatar.lockPressed(true); 151f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren mActiveUserAvatar.setActive(false, true, new Runnable() { 152f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren @Override 153f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren public void run() { 154f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren mActiveUserAvatar = avatar; 1555ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller try { 1565ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller ActivityManagerNative.getDefault() 1575ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller .switchUser(avatar.getUserInfo().id); 1585ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller } catch (RemoteException re) { 1595ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller Log.e(TAG, "Couldn't switch user " + re); 160f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren } 161f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren } 162f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren }); 163f0fd172a7d4a71da413e5bb6aad9ef611ce2a837Chris Wren } 16424b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen } 16566b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen } 16666b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen} 167