diff options
author | Adrian Roos <roosa@google.com> | 2014-08-07 12:47:22 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-08-07 09:28:12 +0000 |
commit | 04e5f72cdb7bbe494e4b330b393388d1e0b18f74 (patch) | |
tree | fae8148a4dd4018a72498c3e712ec904d9a04c03 /packages/SystemUI/src | |
parent | 2e7cf64842aadcf198ee97d137ccbb02ee2115fd (diff) | |
parent | ccdff62159b41ab130a8f90d30edb9b9542d8c72 (diff) | |
download | frameworks_base-04e5f72cdb7bbe494e4b330b393388d1e0b18f74.zip frameworks_base-04e5f72cdb7bbe494e4b330b393388d1e0b18f74.tar.gz frameworks_base-04e5f72cdb7bbe494e4b330b393388d1e0b18f74.tar.bz2 |
Merge "Update User switcher to new spec, implement adding users" into lmp-dev
Diffstat (limited to 'packages/SystemUI/src')
6 files changed, 164 insertions, 39 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java index d765aab..759d540 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java @@ -16,11 +16,14 @@ package com.android.systemui.qs.tiles; +import com.android.internal.util.ArrayUtils; import com.android.systemui.R; import com.android.systemui.statusbar.phone.UserAvatarView; import android.content.Context; +import android.content.res.TypedArray; import android.graphics.Bitmap; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.LayoutInflater; @@ -36,6 +39,8 @@ public class UserDetailItemView extends LinearLayout { private UserAvatarView mAvatar; private TextView mName; + private Typeface mRegularTypeface; + private Typeface mActivatedTypeface; public UserDetailItemView(Context context) { this(context, null); @@ -52,6 +57,21 @@ public class UserDetailItemView extends LinearLayout { public UserDetailItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + final TypedArray a = context.obtainStyledAttributes( + attrs, R.styleable.UserDetailItemView, defStyleAttr, defStyleRes); + final int N = a.getIndexCount(); + for (int i = 0; i < N; i++) { + int attr = a.getIndex(i); + switch (attr) { + case R.styleable.UserDetailItemView_regularFontFamily: + mRegularTypeface = Typeface.create(a.getString(attr), 0 /* style */); + break; + case R.styleable.UserDetailItemView_activatedFontFamily: + mActivatedTypeface = Typeface.create(a.getString(attr), 0 /* style */); + break; + } + } + a.recycle(); } public static UserDetailItemView convertOrInflate(Context context, View convertView, @@ -77,6 +97,23 @@ public class UserDetailItemView extends LinearLayout { protected void onFinishInflate() { mAvatar = (UserAvatarView) findViewById(R.id.user_picture); mName = (TextView) findViewById(R.id.user_name); + if (mRegularTypeface == null) { + mRegularTypeface = mName.getTypeface(); + } + if (mActivatedTypeface == null) { + mActivatedTypeface = mName.getTypeface(); + } + updateTypeface(); } + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); + updateTypeface(); + } + + private void updateTypeface() { + boolean activated = ArrayUtils.contains(getDrawableState(), android.R.attr.state_activated); + mName.setTypeface(activated ? mActivatedTypeface : mRegularTypeface); + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java index 67eef56..8cff81a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java @@ -83,7 +83,7 @@ public class UserDetailView extends GridView { mContext, convertView, parent); String name = getName(mContext, item); if (item.picture == null) { - v.bind(name, mContext.getDrawable(R.drawable.ic_account_circle_qs)); + v.bind(name, getDrawable(mContext, item)); } else { v.bind(name, item.picture); } 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 015a21d..e8b167c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -799,9 +799,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mFlashlightController = new FlashlightController(mContext); mKeyguardBottomArea.setFlashlightController(mFlashlightController); - mUserSwitcherController = new UserSwitcherController(mContext); mNextAlarmController = new NextAlarmController(mContext); mKeyguardMonitor = new KeyguardMonitor(); + mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor); mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext, (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java index 93561aa..101a5f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java @@ -38,6 +38,7 @@ public class UserAvatarView extends View { private int mActiveFrameColor; private int mFrameColor; private float mFrameWidth; + private float mFramePadding; private Bitmap mBitmap; private Drawable mDrawable; @@ -60,6 +61,9 @@ public class UserAvatarView extends View { case R.styleable.UserAvatarView_frameWidth: setFrameWidth(a.getDimension(attr, 0)); break; + case R.styleable.UserAvatarView_framePadding: + setFramePadding(a.getDimension(attr, 0)); + break; case R.styleable.UserAvatarView_activeFrameColor: setActiveFrameColor(a.getColor(attr, 0)); break; @@ -115,6 +119,11 @@ public class UserAvatarView extends View { invalidate(); } + public void setFramePadding(float framePadding) { + mFramePadding = framePadding; + invalidate(); + } + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); @@ -131,11 +140,11 @@ public class UserAvatarView extends View { dwidth = mBitmap.getWidth(); dheight = mBitmap.getHeight(); } else if (mDrawable != null) { - dwidth = mDrawable.getIntrinsicWidth(); - dheight = mDrawable.getIntrinsicHeight(); - mDrawable.setBounds(0, 0, dwidth, dheight); vwidth -= 2 * (mFrameWidth - 1); vheight -= 2 * (mFrameWidth - 1); + dwidth = vwidth; + dheight = vheight; + mDrawable.setBounds(0, 0, dwidth, dheight); } else { return; } @@ -183,7 +192,8 @@ public class UserAvatarView extends View { if (frameColor != 0) { mFramePaint.setColor(frameColor); mFramePaint.setStrokeWidth(mFrameWidth); - canvas.drawCircle(halfW, halfH, halfSW - mFrameWidth / 2f, mFramePaint); + canvas.drawCircle(halfW, halfH, halfSW + (mFramePadding - mFrameWidth) / 2f, + mFramePaint); } } 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 a0312bc..ffc6898 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java @@ -26,6 +26,7 @@ import android.view.ViewStub; import android.widget.TextView; import com.android.systemui.R; +import com.android.systemui.qs.tiles.UserDetailItemView; import com.android.systemui.statusbar.phone.KeyguardStatusBarView; import com.android.systemui.statusbar.phone.UserAvatarView; @@ -140,21 +141,19 @@ public class KeyguardUserSwitcher { public View getView(int position, View convertView, ViewGroup parent) { UserSwitcherController.UserRecord item = getItem(position); - if (convertView == null + if (!(convertView instanceof UserDetailItemView) || !(convertView.getTag() instanceof UserSwitcherController.UserRecord)) { convertView = LayoutInflater.from(mContext).inflate( R.layout.keyguard_user_switcher_item, parent, false); convertView.setOnClickListener(this); } + UserDetailItemView v = (UserDetailItemView) convertView; - TextView nameView = (TextView) convertView.findViewById(R.id.name); - UserAvatarView pictureView = (UserAvatarView) convertView.findViewById(R.id.picture); - - nameView.setText(getName(mContext, item)); + String name = getName(mContext, item); if (item.picture == null) { - pictureView.setDrawable(mContext.getDrawable(R.drawable.ic_account_circle_qs)); + v.bind(name, getDrawable(mContext, item)); } else { - pictureView.setBitmap(item.picture); + v.bind(name, item.picture); } convertView.setActivated(item.isCurrent); convertView.setTag(item); 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 6e3656d..c48f3f5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -34,6 +34,7 @@ import android.content.IntentFilter; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Handler; import android.os.RemoteException; @@ -68,15 +69,18 @@ public class UserSwitcherController { private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>(); private final GuestResumeSessionReceiver mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(); - private boolean mSimpleUserSwitcher; + private final KeyguardMonitor mKeyguardMonitor; private ArrayList<UserRecord> mUsers = new ArrayList<>(); private Dialog mExitGuestDialog; private int mLastNonGuestUser = UserHandle.USER_OWNER; + private boolean mSimpleUserSwitcher; + private boolean mAddUsersWhenLocked; - public UserSwitcherController(Context context) { + public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor) { mContext = context; mGuestResumeSessionReceiver.register(context); + mKeyguardMonitor = keyguardMonitor; mUserManager = UserManager.get(context); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_ADDED); @@ -87,11 +91,17 @@ public class UserSwitcherController { mContext.registerReceiverAsUser(mReceiver, UserHandle.OWNER, filter, null /* permission */, null /* scheduler */); - mSimpleUserSwitcher = Settings.Global.getInt(context.getContentResolver(), - SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0; + mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true, - mSimpleUserSwitcherObserver); + mSettingsObserver); + mContext.getContentResolver().registerContentObserver( + Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true, + mSettingsObserver); + // Fetch initial values. + mSettingsObserver.onChange(false); + + keyguardMonitor.addCallback(mCallback); refreshUsers(UserHandle.USER_NULL); } @@ -116,6 +126,7 @@ public class UserSwitcherController { bitmaps.put(r.info.id, r.picture); } + final boolean addUsersWhenLocked = mAddUsersWhenLocked; new AsyncTask<SparseArray<Bitmap>, Void, ArrayList<UserRecord>>() { @SuppressWarnings("unchecked") @Override @@ -135,7 +146,8 @@ public class UserSwitcherController { boolean isCurrent = currentId == info.id; if (info.isGuest()) { guestRecord = new UserRecord(info, null /* picture */, - true /* isGuest */, isCurrent); + true /* isGuest */, isCurrent, false /* isAddUser */, + false /* isRestricted */); } else if (info.supportsSwitchTo()) { Bitmap picture = bitmaps.get(info.id); if (picture == null) { @@ -145,19 +157,40 @@ public class UserSwitcherController { picture = BitmapHelper.createCircularClip( picture, avatarSize, avatarSize); } - records.add(new UserRecord(info, picture, false /* isGuest */, isCurrent)); + records.add(new UserRecord(info, picture, false /* isGuest */, isCurrent, + false /* isAddUser */, false /* isRestricted */)); } } + boolean ownerCanCreateUsers = !mUserManager.hasUserRestriction( + UserManager.DISALLOW_ADD_USER, UserHandle.OWNER); + boolean currentUserCanCreateUsers = + (currentId == UserHandle.USER_OWNER) && ownerCanCreateUsers; + boolean anyoneCanCreateUsers = ownerCanCreateUsers && addUsersWhenLocked; + boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers) + && guestRecord == null; + boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers) + && records.size() < UserManager.getMaxSupportedUsers(); + boolean createIsRestricted = !addUsersWhenLocked; + if (!mSimpleUserSwitcher) { if (guestRecord == null) { - records.add(new UserRecord(null /* info */, null /* picture */, - true /* isGuest */, false /* isCurrent */)); + if (canCreateGuest) { + records.add(new UserRecord(null /* info */, null /* picture */, + true /* isGuest */, false /* isCurrent */, + false /* isAddUser */, createIsRestricted)); + } } else { records.add(guestRecord); } } + if (canCreateUser) { + records.add(new UserRecord(null /* info */, null /* picture */, + false /* isGuest */, false /* isCurrent */, true /* isAddUser */, + createIsRestricted)); + } + return records; } @@ -168,7 +201,7 @@ public class UserSwitcherController { notifyAdapters(); } } - }.execute((SparseArray)bitmaps); + }.execute((SparseArray) bitmaps); } private void notifyAdapters() { @@ -190,8 +223,10 @@ public class UserSwitcherController { int id; if (record.isGuest && record.info == null) { // No guest user. Create one. - id = mUserManager.createGuest(mContext, - mContext.getResources().getString(R.string.guest_nickname)).id; + id = mUserManager.createGuest(mContext, mContext.getString(R.string.guest_nickname)).id; + } else if (record.isAddUser) { + id = mUserManager.createUser( + mContext.getString(R.string.user_new_user_name), 0 /* flags */).id; } else { id = record.info.id; } @@ -260,6 +295,11 @@ public class UserSwitcherController { if (shouldBeCurrent && !record.isGuest) { mLastNonGuestUser = record.info.id; } + if (currentId != UserHandle.USER_OWNER && record.isRestricted) { + // Immediately remove restricted records in case the AsyncTask is too slow. + mUsers.remove(i); + i--; + } } notifyAdapters(); } @@ -272,10 +312,12 @@ public class UserSwitcherController { } }; - private final ContentObserver mSimpleUserSwitcherObserver = new ContentObserver(new Handler()) { + private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { public void onChange(boolean selfChange) { mSimpleUserSwitcher = Settings.Global.getInt(mContext.getContentResolver(), SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0; + mAddUsersWhenLocked = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0; refreshUsers(UserHandle.USER_NULL); }; }; @@ -301,7 +343,22 @@ public class UserSwitcherController { @Override public int getCount() { - return mController.mUsers.size(); + boolean secureKeyguardShowing = mController.mKeyguardMonitor.isShowing() + && mController.mKeyguardMonitor.isSecure(); + if (!secureKeyguardShowing) { + return mController.mUsers.size(); + } + // The lock screen is secure and showing. Filter out restricted records. + final int N = mController.mUsers.size(); + int count = 0; + for (int i = 0; i < N; i++) { + if (mController.mUsers.get(i).isRestricted) { + break; + } else { + count++; + } + } + return count; } @Override @@ -326,6 +383,8 @@ public class UserSwitcherController { return context.getString( item.info == null ? R.string.guest_new_guest : R.string.guest_nickname); } + } else if (item.isAddUser) { + return context.getString(R.string.user_add_user); } else { return item.info.name; } @@ -342,6 +401,13 @@ public class UserSwitcherController { } return result; } + + public Drawable getDrawable(Context context, UserRecord item) { + if (item.isAddUser) { + return context.getDrawable(R.drawable.ic_add_circle_qs); + } + return context.getDrawable(R.drawable.ic_account_circle_qs); + } } public static final class UserRecord { @@ -349,16 +415,22 @@ public class UserSwitcherController { public final Bitmap picture; public final boolean isGuest; public final boolean isCurrent; + public final boolean isAddUser; + /** If true, the record is only visible to the owner and only when unlocked. */ + public final boolean isRestricted; - public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent) { + public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent, + boolean isAddUser, boolean isRestricted) { this.info = info; this.picture = picture; this.isGuest = isGuest; this.isCurrent = isCurrent; + this.isAddUser = isAddUser; + this.isRestricted = isRestricted; } public UserRecord copyWithIsCurrent(boolean _isCurrent) { - return new UserRecord(info, picture, isGuest, _isCurrent); + return new UserRecord(info, picture, isGuest, _isCurrent, isAddUser, isRestricted); } public String toString() { @@ -367,17 +439,17 @@ public class UserSwitcherController { if (info != null) { sb.append("name=\"" + info.name + "\" id=" + info.id); } else { - sb.append("<add guest placeholder>"); - } - if (isGuest) { - sb.append(" <isGuest>"); - } - if (isCurrent) { - sb.append(" <isCurrent>"); - } - if (picture != null) { - sb.append(" <hasPicture>"); + if (isGuest) { + sb.append("<add guest placeholder>"); + } else if (isAddUser) { + sb.append("<add user placeholder>"); + } } + if (isGuest) sb.append(" <isGuest>"); + if (isAddUser) sb.append(" <isAddUser>"); + if (isCurrent) sb.append(" <isCurrent>"); + if (picture != null) sb.append(" <hasPicture>"); + if (isRestricted) sb.append(" <isRestricted>"); sb.append(')'); return sb.toString(); } @@ -418,6 +490,13 @@ public class UserSwitcherController { } }; + private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() { + @Override + public void onKeyguardChanged() { + notifyAdapters(); + } + }; + private final class ExitGuestDialog extends SystemUIDialog implements DialogInterface.OnClickListener { |