diff options
5 files changed, 126 insertions, 129 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java index 688c0d84cfa4..af302662e070 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java @@ -26,7 +26,7 @@ import android.view.View; import android.widget.FrameLayout; import com.android.systemui.qs.QSPanel; -import com.android.systemui.qs.tiles.UserDetailView; +import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; /** * Container for image of the multi user switcher (tappable). @@ -34,6 +34,8 @@ import com.android.systemui.qs.tiles.UserDetailView; public class MultiUserSwitch extends FrameLayout implements View.OnClickListener { private QSPanel mQsPanel; + private KeyguardUserSwitcher mKeyguardUserSwitcher; + private boolean mKeyguardMode; public MultiUserSwitch(Context context, AttributeSet attrs) { super(context, attrs); @@ -49,12 +51,26 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener mQsPanel = qsPanel; } + public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) { + mKeyguardUserSwitcher = keyguardUserSwitcher; + } + + public void setKeyguardMode(boolean keyguardShowing) { + mKeyguardMode = keyguardShowing; + } + @Override public void onClick(View v) { final UserManager um = UserManager.get(getContext()); if (um.isUserSwitcherEnabled()) { - mQsPanel.showDetailAdapter(true, - mQsPanel.getHost().getUserSwitcherController().userDetailAdapter); + if (mKeyguardMode) { + if (mKeyguardUserSwitcher != null) { + mKeyguardUserSwitcher.show(); + } + } else { + mQsPanel.showDetailAdapter(true, + mQsPanel.getHost().getUserSwitcherController().userDetailAdapter); + } } else { Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent( getContext(), v, ContactsContract.Profile.CONTENT_URI, 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 46a32da3bc14..b3b70e814265 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -737,9 +737,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, final SignalClusterView signalCluster = (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster); - mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext, - (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), mHeader); - mNetworkController.addSignalCluster(signalCluster); signalCluster.setNetworkController(mNetworkController); final boolean isAPhone = mNetworkController.hasVoiceCallingFeature(); @@ -775,6 +772,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mUserSwitcherController = new UserSwitcherController(mContext); mKeyguardMonitor = new KeyguardMonitor(); + mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext, + (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), mHeader, + mUserSwitcherController); + + // Set up the quick settings tile panel mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel); if (mQSPanel != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index 2f88e21c315a..1290cd132571 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -35,6 +35,7 @@ import com.android.systemui.R; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.policy.BatteryController; +import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.UserInfoController; /** @@ -97,6 +98,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private ActivityStarter mActivityStarter; private BatteryController mBatteryController; private QSPanel mQSPanel; + private boolean mHasKeyguardUserSwitcher; private final Rect mClipBounds = new Rect(); private final StatusIconClipper mStatusIconClipper = new StatusIconClipper(); @@ -373,7 +375,11 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private void updateClickTargets() { setClickable(!mKeyguardShowing || mExpanded); mDateTime.setClickable(mExpanded); - mMultiUserSwitch.setClickable(mExpanded); + + boolean keyguardSwitcherAvailable = + mHasKeyguardUserSwitcher && mKeyguardShowing && !mExpanded; + mMultiUserSwitch.setClickable(mExpanded || keyguardSwitcherAvailable); + mMultiUserSwitch.setKeyguardMode(keyguardSwitcherAvailable); mSystemIconsSuperContainer.setClickable(mExpanded); } @@ -509,6 +515,11 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mMultiUserSwitch.setQsPanel(qsp); } + public void setKeyguarUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) { + mHasKeyguardUserSwitcher = true; + mMultiUserSwitch.setKeyguardUserSwitcher(keyguardUserSwitcher); + } + @Override public boolean shouldDelayChildPressedState() { return true; @@ -522,7 +533,6 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } public void setKeyguardUserSwitcherShowing(boolean showing) { - // STOPSHIP: NOT CALLED PROPERLY WHEN GOING TO FULL SHADE AND RETURNING!?! mKeyguardUserSwitcherShowing = showing; updateVisibilities(); updateSystemIconsLayoutParams(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java index a3f381907452..b0bab48d6c34 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java @@ -16,62 +16,56 @@ package com.android.systemui.statusbar.policy; -import com.android.systemui.BitmapHelper; import com.android.systemui.R; import com.android.systemui.statusbar.phone.StatusBarHeaderView; import com.android.systemui.statusbar.phone.UserAvatarView; -import android.app.ActivityManagerNative; import android.content.Context; -import android.content.pm.UserInfo; -import android.graphics.Bitmap; -import android.os.AsyncTask; -import android.os.RemoteException; -import android.os.UserManager; -import android.util.Log; +import android.database.DataSetObserver; +import android.provider.Settings; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewStub; -import android.view.WindowManagerGlobal; import android.widget.TextView; -import java.util.ArrayList; -import java.util.List; - /** * Manages the user switcher on the Keyguard. */ -public class KeyguardUserSwitcher implements View.OnClickListener { +public class KeyguardUserSwitcher { private static final String TAG = "KeyguardUserSwitcher"; + private static final boolean ALWAYS_ON = false; + private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING = + "lockscreenSimpleUserSwitcher"; - private final Context mContext; private final ViewGroup mUserSwitcher; - private final UserManager mUserManager; private final StatusBarHeaderView mHeader; + private final Adapter mAdapter; + private final boolean mSimpleUserSwitcher; public KeyguardUserSwitcher(Context context, ViewStub userSwitcher, - StatusBarHeaderView header) { - mContext = context; - if (context.getResources().getBoolean(R.bool.config_keyguardUserSwitcher)) { + StatusBarHeaderView header, UserSwitcherController userSwitcherController) { + if (context.getResources().getBoolean(R.bool.config_keyguardUserSwitcher) || ALWAYS_ON) { mUserSwitcher = (ViewGroup) userSwitcher.inflate(); - mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mHeader = header; - refresh(); + mHeader.setKeyguarUserSwitcher(this); + mAdapter = new Adapter(context, userSwitcherController); + mAdapter.registerDataSetObserver(mDataSetObserver); + mSimpleUserSwitcher = Settings.Global.getInt(context.getContentResolver(), + SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0; } else { mUserSwitcher = null; - mUserManager = null; mHeader = null; + mAdapter = null; + mSimpleUserSwitcher = false; } } public void setKeyguard(boolean keyguard) { if (mUserSwitcher != null) { - // TODO: Cache showUserSwitcherOnKeyguard(). - if (keyguard && showUserSwitcherOnKeyguard()) { + if (keyguard && shouldExpandByDefault()) { show(); - refresh(); } else { hide(); } @@ -79,24 +73,11 @@ public class KeyguardUserSwitcher implements View.OnClickListener { } /** - * @return true if the user switcher should be shown on the lock screen. + * @return true if the user switcher should be expanded by default on the lock screen. * @see android.os.UserManager#isUserSwitcherEnabled() */ - private boolean showUserSwitcherOnKeyguard() { - // TODO: Set isEdu. The edu provisioning process can add settings to Settings.Global. - boolean isEdu = false; - if (isEdu) { - return true; - } - List<UserInfo> users = mUserManager.getUsers(true /* excludeDying */); - int N = users.size(); - int switchableUsers = 0; - for (int i = 0; i < N; i++) { - if (users.get(i).supportsSwitchTo()) { - switchableUsers++; - } - } - return switchableUsers > 1; + private boolean shouldExpandByDefault() { + return mSimpleUserSwitcher || mAdapter.getSwitchableUsers() > 1; } public void show() { @@ -116,100 +97,76 @@ public class KeyguardUserSwitcher implements View.OnClickListener { } private void refresh() { - if (mUserSwitcher != null) { - new AsyncTask<Void, Void, ArrayList<UserData>>() { - @Override - protected ArrayList<UserData> doInBackground(Void... params) { - return loadUsers(); + final int childCount = mUserSwitcher.getChildCount(); + final int adapterCount = mAdapter.getCount(); + final int N = Math.max(childCount, adapterCount); + for (int i = 0; i < N; i++) { + if (i < adapterCount) { + View oldView = null; + if (i < childCount) { + oldView = mUserSwitcher.getChildAt(i); } - - @Override - protected void onPostExecute(ArrayList<UserData> userInfos) { - bind(userInfos); + View newView = mAdapter.getView(i, oldView, mUserSwitcher); + if (oldView == null) { + // We ran out of existing views. Add it at the end. + mUserSwitcher.addView(newView); + } else if (oldView != newView) { + // We couldn't rebind the view. Replace it. + mUserSwitcher.removeViewAt(i); + mUserSwitcher.addView(newView, i); } - }.execute((Void[]) null); + } else { + int lastIndex = mUserSwitcher.getChildCount() - 1; + mUserSwitcher.removeViewAt(lastIndex); + } } } - private void bind(ArrayList<UserData> userList) { - mUserSwitcher.removeAllViews(); - int N = userList.size(); - for (int i = 0; i < N; i++) { - mUserSwitcher.addView(inflateUser(userList.get(i))); + public final DataSetObserver mDataSetObserver = new DataSetObserver() { + @Override + public void onChanged() { + refresh(); } - // TODO: add Guest - // TODO: add (+) button - } + }; - private View inflateUser(UserData user) { - View v = LayoutInflater.from(mUserSwitcher.getContext()).inflate( - R.layout.keyguard_user_switcher_item, mUserSwitcher, false); - TextView name = (TextView) v.findViewById(R.id.name); - UserAvatarView picture = (UserAvatarView) v.findViewById(R.id.picture); - name.setText(user.userInfo.name); - picture.setActivated(user.isCurrent); - if (user.userInfo.isGuest()) { - picture.setDrawable(mContext.getResources().getDrawable(R.drawable.ic_account_circle)); - } else { - picture.setBitmap(user.userIcon); - } - v.setOnClickListener(this); - v.setTag(user.userInfo); - // TODO: mark which user is current for accessibility. - return v; - } + public static class Adapter extends UserSwitcherController.BaseUserAdapter implements + View.OnClickListener { - @Override - public void onClick(View v) { - switchUser(((UserInfo)v.getTag()).id); - } + private Context mContext; - // TODO: Factor out logic below and share with QS implementation. - - private ArrayList<UserData> loadUsers() { - ArrayList<UserInfo> users = (ArrayList<UserInfo>) mUserManager - .getUsers(true /* excludeDying */); - int N = users.size(); - ArrayList<UserData> result = new ArrayList<>(N); - int currentUser = -1; - try { - currentUser = ActivityManagerNative.getDefault().getCurrentUser().id; - } catch (RemoteException e) { - Log.e(TAG, "Couln't get current user.", e); + public Adapter(Context context, UserSwitcherController controller) { + super(controller); + mContext = context; } - final int avatarSize - = mContext.getResources().getDimensionPixelSize(R.dimen.max_avatar_size); - for (int i = 0; i < N; i++) { - UserInfo user = users.get(i); - if (user.supportsSwitchTo()) { - boolean isCurrent = user.id == currentUser; - final Bitmap picture = BitmapHelper.createCircularClip( - mUserManager.getUserIcon(user.id), - avatarSize, avatarSize); - result.add(new UserData(user, picture, isCurrent)); + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + UserSwitcherController.UserRecord item = getItem(position); + + if (convertView == null + || !(convertView.getTag() instanceof UserSwitcherController.UserRecord)) { + convertView = LayoutInflater.from(mContext).inflate( + R.layout.keyguard_user_switcher_item, parent, false); + convertView.setOnClickListener(this); } - } - return result; - } - private void switchUser(int userId) { - try { - WindowManagerGlobal.getWindowManagerService().lockNow(null); - ActivityManagerNative.getDefault().switchUser(userId); - } catch (RemoteException e) { - Log.e(TAG, "Couldn't switch user.", e); - } - } + TextView nameView = (TextView) convertView.findViewById(R.id.name); + UserAvatarView pictureView = (UserAvatarView) convertView.findViewById(R.id.picture); - private static class UserData { - final UserInfo userInfo; - final Bitmap userIcon; - final boolean isCurrent; + nameView.setText(getName(mContext, item)); + if (item.picture == null) { + pictureView.setDrawable(mContext.getDrawable(R.drawable.ic_account_circle_qs)); + } else { + pictureView.setBitmap(item.picture); + } + convertView.setActivated(item.isCurrent); + convertView.setTag(item); + return convertView; + } - UserData(UserInfo userInfo, Bitmap userIcon, boolean isCurrent) { - this.userInfo = userInfo; - this.userIcon = userIcon; - this.isCurrent = isCurrent; + @Override + public void onClick(View v) { + switchTo(((UserSwitcherController.UserRecord)v.getTag())); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index 7bf2c3480b93..7c00c7fe074a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -123,7 +123,7 @@ public class UserSwitcherController { if (info.isGuest()) { guestRecord = new UserRecord(info, null /* picture */, true /* isGuest */, isCurrent); - } else if (!info.isManagedProfile()) { + } else if (info.supportsSwitchTo()) { Bitmap picture = bitmaps.get(info.id); if (picture == null) { picture = mUserManager.getUserIcon(info.id); @@ -303,6 +303,18 @@ public class UserSwitcherController { return item.info.name; } } + + public int getSwitchableUsers() { + int result = 0; + ArrayList<UserRecord> users = mController.mUsers; + int N = users.size(); + for (int i = 0; i < N; i++) { + if (users.get(i).info != null) { + result++; + } + } + return result; + } } public static final class UserRecord { |