Skip to content

Commit 6f2a3d2

Browse files
committed
Quick settings user display and switching
Load user information for the current user and display in quick settings tile. Name is pulled from the contacts DB from the "Me" profile, which will override the raw name on the system user if needed. Open the user switcher on the lock screen if this tile is clicked and there is more than one user registered on the system. If there is only one user, show the "Me" quick contact card. Darken the background protection behind the user's name on the QS tile layout so that it's readable against very light profile pic backgrounds. Bug 7175023 Bug 7257997 Change-Id: Ia1e7dd7af72dbd49113a827f9228e0a32e20a0dc
1 parent d9c9912 commit 6f2a3d2

File tree

3 files changed

+127
-64
lines changed

3 files changed

+127
-64
lines changed

core/java/android/app/ContextImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,8 +1702,8 @@ public Context createPackageContextAsUser(String packageName, int flags, UserHan
17021702
throws NameNotFoundException {
17031703
if (packageName.equals("system") || packageName.equals("android")) {
17041704
final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
1705-
context.mBasePackageName = mBasePackageName;
1706-
context.mUser = user;
1705+
context.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1706+
context.init(mPackageInfo, null, mMainThread, mResources, mBasePackageName, user);
17071707
return context;
17081708
}
17091709

packages/SystemUI/res/layout/quick_settings_tile_user.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@
3232
android:layout_gravity="center_horizontal|bottom"
3333
android:gravity="center"
3434
android:text="@string/quick_settings_user_label"
35-
android:background="#33000000"
35+
android:background="#CC000000"
3636
/>
3737
</FrameLayout>

packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java

Lines changed: 124 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@
1616

1717
package com.android.systemui.statusbar.phone;
1818

19+
import com.android.internal.view.RotationPolicy;
20+
import com.android.internal.widget.LockPatternUtils;
21+
import com.android.systemui.R;
22+
import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState;
23+
import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
24+
import com.android.systemui.statusbar.phone.QuickSettingsModel.UserState;
25+
import com.android.systemui.statusbar.policy.BatteryController;
26+
import com.android.systemui.statusbar.policy.BluetoothController;
27+
import com.android.systemui.statusbar.policy.BrightnessController;
28+
import com.android.systemui.statusbar.policy.LocationController;
29+
import com.android.systemui.statusbar.policy.NetworkController;
30+
import com.android.systemui.statusbar.policy.ToggleSlider;
31+
1932
import android.app.ActivityManagerNative;
2033
import android.app.AlertDialog;
2134
import android.app.Dialog;
@@ -29,49 +42,44 @@
2942
import android.content.DialogInterface.OnClickListener;
3043
import android.content.Intent;
3144
import android.content.IntentFilter;
32-
import android.content.Loader;
45+
import android.content.pm.PackageManager.NameNotFoundException;
46+
import android.content.pm.UserInfo;
3347
import android.content.res.Resources;
3448
import android.database.Cursor;
49+
import android.graphics.Bitmap;
3550
import android.graphics.drawable.BitmapDrawable;
3651
import android.graphics.drawable.Drawable;
3752
import android.graphics.drawable.LevelListDrawable;
3853
import android.hardware.display.DisplayManager;
3954
import android.hardware.display.WifiDisplayStatus;
40-
import android.net.Uri;
55+
import android.os.AsyncTask;
4156
import android.os.Handler;
4257
import android.os.RemoteException;
43-
import android.os.SystemProperties;
4458
import android.os.UserHandle;
4559
import android.os.UserManager;
4660
import android.provider.ContactsContract;
61+
import android.provider.ContactsContract.CommonDataKinds.Phone;
62+
import android.provider.ContactsContract.Profile;
4763
import android.provider.Settings;
64+
import android.util.Log;
65+
import android.util.Pair;
4866
import android.view.LayoutInflater;
4967
import android.view.View;
5068
import android.view.ViewGroup;
5169
import android.view.Window;
5270
import android.view.WindowManager;
71+
import android.view.WindowManagerGlobal;
5372
import android.widget.ImageView;
5473
import android.widget.TextView;
5574

56-
import com.android.internal.view.RotationPolicy;
57-
import com.android.systemui.R;
58-
import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState;
59-
import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
60-
import com.android.systemui.statusbar.phone.QuickSettingsModel.UserState;
61-
import com.android.systemui.statusbar.policy.BatteryController;
62-
import com.android.systemui.statusbar.policy.BluetoothController;
63-
import com.android.systemui.statusbar.policy.BrightnessController;
64-
import com.android.systemui.statusbar.policy.LocationController;
65-
import com.android.systemui.statusbar.policy.NetworkController;
66-
import com.android.systemui.statusbar.policy.ToggleSlider;
67-
6875
import java.util.ArrayList;
6976

7077

7178
/**
7279
*
7380
*/
7481
class QuickSettings {
82+
private static final String TAG = "QuickSettings";
7583
public static final boolean SHOW_IME_TILE = false;
7684

7785
private Context mContext;
@@ -91,11 +99,13 @@ class QuickSettings {
9199
private int mBrightnessDialogShortTimeout;
92100
private int mBrightnessDialogLongTimeout;
93101

94-
private CursorLoader mUserInfoLoader;
102+
private AsyncTask<Void, Void, Pair<String, BitmapDrawable>> mUserInfoTask;
95103

96104
private LevelListDrawable mBatteryLevels;
97105
private LevelListDrawable mChargingBatteryLevels;
98106

107+
boolean mTilesSetUp = false;
108+
99109
private Handler mHandler;
100110

101111
// The set of QuickSettingsTiles that have dynamic spans (and need to be updated on
@@ -132,7 +142,14 @@ public QuickSettings(Context context, QuickSettingsContainerView container) {
132142
IntentFilter filter = new IntentFilter();
133143
filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
134144
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
145+
filter.addAction(Intent.ACTION_USER_SWITCHED);
135146
mContext.registerReceiver(mReceiver, filter);
147+
148+
IntentFilter profileFilter = new IntentFilter();
149+
profileFilter.addAction(ContactsContract.Intents.ACTION_PROFILE_CHANGED);
150+
profileFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
151+
mContext.registerReceiverAsUser(mProfileReceiver, UserHandle.ALL, profileFilter,
152+
null, null);
136153
}
137154

138155
void setBar(PanelBar bar) {
@@ -168,47 +185,51 @@ void setup(NetworkController networkController, BluetoothController bluetoothCon
168185
}
169186

170187
private void queryForUserInformation() {
171-
System.out.println("queryForUserInformation");
188+
Context currentUserContext = null;
189+
UserInfo userInfo = null;
190+
try {
191+
userInfo = ActivityManagerNative.getDefault().getCurrentUser();
192+
currentUserContext = mContext.createPackageContextAsUser("android", 0,
193+
new UserHandle(userInfo.id));
194+
} catch (NameNotFoundException e) {
195+
Log.e(TAG, "Couldn't create user context", e);
196+
throw new RuntimeException(e);
197+
} catch (RemoteException e) {
198+
Log.e(TAG, "Couldn't get user info", e);
199+
}
200+
final int userId = userInfo.id;
172201

173-
Uri userContactUri = Uri.withAppendedPath(
174-
ContactsContract.Profile.CONTENT_URI,
175-
ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
202+
final Context context = currentUserContext;
203+
mUserInfoTask = new AsyncTask<Void, Void, Pair<String, BitmapDrawable>>() {
204+
@Override
205+
protected Pair<String, BitmapDrawable> doInBackground(Void... params) {
206+
Cursor cursor = context.getContentResolver().query(
207+
Profile.CONTENT_URI, new String[] {Phone._ID, Phone.DISPLAY_NAME},
208+
null, null, null);
209+
210+
String name = null;
211+
try {
212+
if (cursor.moveToFirst()) {
213+
name = cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME));
214+
}
215+
} finally {
216+
cursor.close();
217+
}
218+
final UserManager userManager =
219+
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
220+
final BitmapDrawable icon = new BitmapDrawable(mContext.getResources(),
221+
userManager.getUserIcon(userId));
222+
return new Pair<String, BitmapDrawable>(name, icon);
223+
}
176224

177-
String[] selectArgs = {
178-
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
179-
ContactsContract.CommonDataKinds.Photo.PHOTO
180-
};
181-
String where = String.format("(%s = ? OR %s = ?) AND %s IS NULL",
182-
ContactsContract.Contacts.Data.MIMETYPE,
183-
ContactsContract.Contacts.Data.MIMETYPE,
184-
ContactsContract.RawContacts.ACCOUNT_TYPE);
185-
String[] whereArgs = {
186-
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
187-
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
225+
@Override
226+
protected void onPostExecute(Pair<String, BitmapDrawable> result) {
227+
super.onPostExecute(result);
228+
mModel.setUserTileInfo(result.first, result.second);
229+
mUserInfoTask = null;
230+
}
188231
};
189-
190-
mUserInfoLoader = new CursorLoader(mContext, userContactUri, selectArgs, where, whereArgs,
191-
null);
192-
mUserInfoLoader.registerListener(0,
193-
new Loader.OnLoadCompleteListener<Cursor>() {
194-
@Override
195-
public void onLoadComplete(Loader<Cursor> loader,
196-
Cursor cursor) {
197-
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
198-
if (cursor != null && cursor.moveToFirst()) {
199-
String name = cursor.getString(0); // DISPLAY_NAME
200-
BitmapDrawable d = new BitmapDrawable(userManager.getUserIcon(userManager.getUserHandle()));
201-
mModel.setUserTileInfo(name, d);
202-
/*
203-
byte[] photoData = cursor.getBlob(0);
204-
Bitmap b =
205-
BitmapFactory.decodeByteArray(photoData, 0, photoData.length);
206-
*/
207-
}
208-
mUserInfoLoader.stopLoading();
209-
}
210-
});
211-
mUserInfoLoader.startLoading();
232+
mUserInfoTask.execute();
212233
}
213234

214235
private void setupQuickSettings() {
@@ -220,6 +241,7 @@ private void setupQuickSettings() {
220241
addTemporaryTiles(mContainerView, inflater);
221242

222243
queryForUserInformation();
244+
mTilesSetUp = true;
223245
}
224246

225247
private void startSettingsActivity(String action) {
@@ -251,10 +273,21 @@ private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
251273
@Override
252274
public void onClick(View v) {
253275
mBar.collapseAllPanels(true);
254-
Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent(mContext,
255-
v, ContactsContract.Profile.CONTENT_URI,
256-
ContactsContract.QuickContact.MODE_LARGE, null);
257-
mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
276+
final UserManager um =
277+
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
278+
if (um.getUsers().size() > 1) {
279+
try {
280+
WindowManagerGlobal.getWindowManagerService().lockNow(
281+
LockPatternUtils.USER_SWITCH_LOCK_OPTIONS);
282+
} catch (RemoteException e) {
283+
Log.e(TAG, "Couldn't show user switcher", e);
284+
}
285+
} else {
286+
Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent(
287+
mContext, v, ContactsContract.Profile.CONTENT_URI,
288+
ContactsContract.QuickContact.MODE_LARGE, null);
289+
mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
290+
}
258291
}
259292
});
260293
mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
@@ -747,20 +780,50 @@ private void applyBluetoothStatus() {
747780
mModel.onBluetoothStateChange(mBluetoothState);
748781
}
749782

783+
void reloadUserInfo() {
784+
if (mUserInfoTask != null) {
785+
mUserInfoTask.cancel(false);
786+
mUserInfoTask = null;
787+
}
788+
if (mTilesSetUp) {
789+
queryForUserInformation();
790+
}
791+
}
792+
750793
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
751794
@Override
752795
public void onReceive(Context context, Intent intent) {
753-
if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
796+
final String action = intent.getAction();
797+
if (DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED.equals(action)) {
754798
WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra(
755799
DisplayManager.EXTRA_WIFI_DISPLAY_STATUS);
756800
mWifiDisplayStatus = status;
757801
applyWifiDisplayStatus();
758-
}
759-
if (intent.getAction().equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
802+
} else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
760803
int status = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
761804
BluetoothAdapter.STATE_DISCONNECTED);
762805
mBluetoothState.connected = (status == BluetoothAdapter.STATE_CONNECTED);
763806
applyBluetoothStatus();
807+
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
808+
reloadUserInfo();
809+
}
810+
}
811+
};
812+
813+
private final BroadcastReceiver mProfileReceiver = new BroadcastReceiver() {
814+
@Override
815+
public void onReceive(Context context, Intent intent) {
816+
final String action = intent.getAction();
817+
if (ContactsContract.Intents.ACTION_PROFILE_CHANGED.equals(action) ||
818+
Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
819+
try {
820+
final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
821+
if (getSendingUserId() == userId) {
822+
reloadUserInfo();
823+
}
824+
} catch (RemoteException e) {
825+
Log.e(TAG, "Couldn't get current user id for profile change", e);
826+
}
764827
}
765828
}
766829
};

0 commit comments

Comments
 (0)