Merge "Eliminating “-1” user serial numbers."
This commit is contained in:
committed by
Android (Google) Code Review
commit
eeea0d92a6
@@ -22,11 +22,6 @@ import android.content.ComponentName;
|
||||
* Navigation bar app information.
|
||||
*/
|
||||
class AppInfo {
|
||||
/**
|
||||
* Unspecified serial number for the app's user.
|
||||
*/
|
||||
public static final long USER_UNSPECIFIED = -1;
|
||||
|
||||
private final ComponentName mComponentName;
|
||||
private final long mUserSerialNumber;
|
||||
|
||||
|
||||
@@ -136,9 +136,10 @@ class NavigationBarApps extends LinearLayout {
|
||||
transition.enableTransitionType(LayoutTransition.CHANGING);
|
||||
parent.setLayoutTransition(transition);
|
||||
|
||||
int currentUserId = ActivityManager.getCurrentUser();
|
||||
mCurrentUserSerialNumber = mUserManager.getSerialNumberForUser(
|
||||
new UserHandle(ActivityManager.getCurrentUser()));
|
||||
sAppsModel.setCurrentUser(mCurrentUserSerialNumber);
|
||||
new UserHandle(currentUserId));
|
||||
sAppsModel.setCurrentUser(currentUserId);
|
||||
recreateAppButtons();
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
@@ -222,10 +223,7 @@ class NavigationBarApps extends LinearLayout {
|
||||
static void startAppDrag(ImageView icon, AppInfo appInfo) {
|
||||
// The drag data is an Intent to launch the activity.
|
||||
Intent mainIntent = Intent.makeMainActivity(appInfo.getComponentName());
|
||||
long userSerialNumber = appInfo.getUserSerialNumber();
|
||||
if (userSerialNumber != AppInfo.USER_UNSPECIFIED) {
|
||||
mainIntent.putExtra(EXTRA_PROFILE, userSerialNumber);
|
||||
}
|
||||
mainIntent.putExtra(EXTRA_PROFILE, appInfo.getUserSerialNumber());
|
||||
ClipData dragData = ClipData.newIntent("", mainIntent);
|
||||
// Use the ImageView to create the shadow.
|
||||
View.DragShadowBuilder shadow = new AppIconDragShadowBuilder(icon);
|
||||
@@ -396,7 +394,14 @@ class NavigationBarApps extends LinearLayout {
|
||||
return null;
|
||||
}
|
||||
|
||||
long userSerialNumber = intent.getLongExtra(EXTRA_PROFILE, AppInfo.USER_UNSPECIFIED);
|
||||
long userSerialNumber = intent.getLongExtra(EXTRA_PROFILE, -1);
|
||||
|
||||
// Validate the received user serial number.
|
||||
UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
|
||||
if (appUser == null) {
|
||||
userSerialNumber = mCurrentUserSerialNumber;
|
||||
}
|
||||
|
||||
return new AppInfo(intent.getComponent(), userSerialNumber);
|
||||
}
|
||||
|
||||
@@ -466,18 +471,14 @@ class NavigationBarApps extends LinearLayout {
|
||||
|
||||
long appUserSerialNumber = appInfo.getUserSerialNumber();
|
||||
|
||||
UserHandle appUser = null;
|
||||
if (appUserSerialNumber != AppInfo.USER_UNSPECIFIED) {
|
||||
appUser = mUserManager.getUserForSerialNumber(appUserSerialNumber);
|
||||
}
|
||||
|
||||
int appUserId;
|
||||
if (appUser != null) {
|
||||
appUserId = appUser.getIdentifier();
|
||||
} else {
|
||||
appUserId = ActivityManager.getCurrentUser();
|
||||
appUser = new UserHandle(appUserId);
|
||||
UserHandle appUser = mUserManager.getUserForSerialNumber(appUserSerialNumber);
|
||||
if (appUser == null) {
|
||||
Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
|
||||
Log.e(TAG, "Can't start activity " + component +
|
||||
" because its user doesn't exist.");
|
||||
return;
|
||||
}
|
||||
int appUserId = appUser.getIdentifier();
|
||||
|
||||
// Play a scale-up animation while launching the activity.
|
||||
// TODO: Consider playing a different animation, or no animation, if the activity is
|
||||
@@ -545,7 +546,7 @@ class NavigationBarApps extends LinearLayout {
|
||||
|
||||
if (newUserSerialNumber != mCurrentUserSerialNumber) {
|
||||
mCurrentUserSerialNumber = newUserSerialNumber;
|
||||
sAppsModel.setCurrentUser(newUserSerialNumber);
|
||||
sAppsModel.setCurrentUser(currentUserId);
|
||||
recreateAppButtons();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,18 +16,16 @@
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -52,7 +50,7 @@ class NavigationBarAppsModel {
|
||||
private final static String VERSION_PREF = "version";
|
||||
|
||||
// Current version number for preferences.
|
||||
private final static int CURRENT_VERSION = 2;
|
||||
private final static int CURRENT_VERSION = 3;
|
||||
|
||||
// Preference name for the number of app icons.
|
||||
private final static String APP_COUNT_PREF = "app_count";
|
||||
@@ -68,18 +66,23 @@ class NavigationBarAppsModel {
|
||||
// user serial of the third app of the logged-in user.
|
||||
private final static char USER_SEPARATOR = '|';
|
||||
|
||||
final Context mContext;
|
||||
private final Context mContext;
|
||||
private final UserManager mUserManager;
|
||||
private final SharedPreferences mPrefs;
|
||||
|
||||
// Apps are represented as an ordered list of app infos.
|
||||
private final List<AppInfo> mApps = new ArrayList<AppInfo>();
|
||||
|
||||
// Id of the current user.
|
||||
private int mCurrentUserId = -1;
|
||||
|
||||
// Serial number of the current user.
|
||||
private long mCurrentUserSerialNumber = AppInfo.USER_UNSPECIFIED;
|
||||
private long mCurrentUserSerialNumber = -1;
|
||||
|
||||
public NavigationBarAppsModel(Context context) {
|
||||
mContext = context;
|
||||
mPrefs = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
|
||||
int version = mPrefs.getInt(VERSION_PREF, -1);
|
||||
if (version != CURRENT_VERSION) {
|
||||
@@ -94,8 +97,9 @@ class NavigationBarAppsModel {
|
||||
/**
|
||||
* Reinitializes the model for a new user.
|
||||
*/
|
||||
public void setCurrentUser(long userSerialNumber) {
|
||||
mCurrentUserSerialNumber = userSerialNumber;
|
||||
public void setCurrentUser(int userId) {
|
||||
mCurrentUserId = userId;
|
||||
mCurrentUserSerialNumber = mUserManager.getSerialNumberForUser(new UserHandle(userId));
|
||||
|
||||
mApps.clear();
|
||||
|
||||
@@ -115,11 +119,8 @@ class NavigationBarAppsModel {
|
||||
* Removes prefs for users that don't exist on the device.
|
||||
*/
|
||||
private void removePrefsForDeletedUsers() {
|
||||
UserManager userManager =
|
||||
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
|
||||
// Build a set of string representations of serial numbers of the device users.
|
||||
final List<UserInfo> users = userManager.getUsers();
|
||||
final List<UserInfo> users = mUserManager.getUsers();
|
||||
final int userCount = users.size();
|
||||
|
||||
final Set<String> userSerials = new HashSet<String> ();
|
||||
@@ -207,31 +208,30 @@ class NavigationBarAppsModel {
|
||||
continue;
|
||||
}
|
||||
ComponentName componentName = ComponentName.unflattenFromString(prefValue);
|
||||
long userSerialNumber = mPrefs.getLong(prefUserForApp(i), AppInfo.USER_UNSPECIFIED);
|
||||
long userSerialNumber = mPrefs.getLong(prefUserForApp(i), -1);
|
||||
if (userSerialNumber == -1) {
|
||||
Slog.w(TAG, "Couldn't find pref " + prefUserForApp(i));
|
||||
// Couldn't find the saved state. Just skip this item.
|
||||
continue;
|
||||
}
|
||||
mApps.add(new AppInfo(componentName, userSerialNumber));
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected int getCurrentUser() {
|
||||
return ActivityManager.getCurrentUser();
|
||||
}
|
||||
|
||||
/** Adds the first few apps from the owner profile. Used for demo purposes. */
|
||||
private void addDefaultApps() {
|
||||
// Get a list of all app activities.
|
||||
final Intent queryIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
queryIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
final int currentUser = getCurrentUser();
|
||||
|
||||
final List<ResolveInfo> apps = mContext.getPackageManager().queryIntentActivitiesAsUser(
|
||||
queryIntent, 0 /* flags */, currentUser);
|
||||
queryIntent, 0 /* flags */, mCurrentUserId);
|
||||
final int appCount = apps.size();
|
||||
for (int i = 0; i < NUM_INITIAL_APPS && i < appCount; i++) {
|
||||
ResolveInfo ri = apps.get(i);
|
||||
ComponentName componentName = new ComponentName(
|
||||
ri.activityInfo.packageName, ri.activityInfo.name);
|
||||
mApps.add(new AppInfo(componentName, AppInfo.USER_UNSPECIFIED));
|
||||
mApps.add(new AppInfo(componentName, mCurrentUserSerialNumber));
|
||||
}
|
||||
|
||||
savePrefs();
|
||||
@@ -239,10 +239,6 @@ class NavigationBarAppsModel {
|
||||
|
||||
/** Returns a pref prefixed with the serial number of the current user. */
|
||||
private String userPrefixed(String pref) {
|
||||
if (mCurrentUserSerialNumber == AppInfo.USER_UNSPECIFIED) {
|
||||
throw new RuntimeException("Current user is not yet set");
|
||||
}
|
||||
|
||||
return Long.toString(mCurrentUserSerialNumber) + USER_SEPARATOR + pref;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.content.pm.PackageManager;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
@@ -231,7 +232,11 @@ class NavigationBarRecents extends LinearLayout {
|
||||
}
|
||||
|
||||
if (DEBUG) Slog.d(TAG, "Start drag with " + intent);
|
||||
NavigationBarApps.startAppDrag(icon, new AppInfo (intent.getComponent(), AppInfo.USER_UNSPECIFIED));
|
||||
|
||||
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
long userSerialNumber = userManager.getSerialNumberForUser(new UserHandle(task.userId));
|
||||
NavigationBarApps.startAppDrag(
|
||||
icon, new AppInfo(intent.getComponent(), userSerialNumber));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
@@ -73,15 +74,12 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
|
||||
|
||||
when(mMockUserManager.getUsers()).thenReturn(new ArrayList<UserInfo>());
|
||||
// Assume the version pref is present and equal to the current version.
|
||||
when(mMockPrefs.getInt("version", -1)).thenReturn(2);
|
||||
when(mMockPrefs.getInt("version", -1)).thenReturn(3);
|
||||
when(mMockPrefs.edit()).thenReturn(mMockEdit);
|
||||
|
||||
mModel = new NavigationBarAppsModel(context) {
|
||||
@Override
|
||||
protected int getCurrentUser() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
when(mMockUserManager.getSerialNumberForUser(new UserHandle(2))).thenReturn(22L);
|
||||
|
||||
mModel = new NavigationBarAppsModel(context);
|
||||
}
|
||||
|
||||
/** Initializes the model from SharedPreferences for a few app activites. */
|
||||
@@ -95,25 +93,23 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
|
||||
when(mMockPrefs.getString("22|app_2", null)).thenReturn("package2/class2");
|
||||
when(mMockPrefs.getLong("22|app_user_2", -1)).thenReturn(239L);
|
||||
|
||||
mModel.setCurrentUser(22L);
|
||||
mModel.setCurrentUser(2);
|
||||
}
|
||||
|
||||
/** Tests initializing the model from SharedPreferences. */
|
||||
public void testInitializeFromPrefs() {
|
||||
initializeModelFromPrefs();
|
||||
assertEquals(3, mModel.getAppCount());
|
||||
assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
|
||||
assertEquals(-1L, mModel.getApp(0).getUserSerialNumber());
|
||||
assertEquals("package1/class1", mModel.getApp(1).getComponentName().flattenToString());
|
||||
assertEquals(45L, mModel.getApp(1).getUserSerialNumber());
|
||||
assertEquals("package2/class2", mModel.getApp(2).getComponentName().flattenToString());
|
||||
assertEquals(239L, mModel.getApp(2).getUserSerialNumber());
|
||||
assertEquals(2, mModel.getAppCount());
|
||||
assertEquals("package1/class1", mModel.getApp(0).getComponentName().flattenToString());
|
||||
assertEquals(45L, mModel.getApp(0).getUserSerialNumber());
|
||||
assertEquals("package2/class2", mModel.getApp(1).getComponentName().flattenToString());
|
||||
assertEquals(239L, mModel.getApp(1).getUserSerialNumber());
|
||||
}
|
||||
|
||||
/** Tests initializing the model when the SharedPreferences aren't available. */
|
||||
public void testInitializeDefaultApps() {
|
||||
// Assume the user's app count pref isn't available.
|
||||
when(mMockPrefs.getInt("0|app_count", -1)).thenReturn(-1);
|
||||
when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(-1);
|
||||
|
||||
// Assume some installed activities.
|
||||
ActivityInfo ai1 = new ActivityInfo();
|
||||
@@ -127,16 +123,16 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
|
||||
ResolveInfo ri2 = new ResolveInfo();
|
||||
ri2.activityInfo = ai2;
|
||||
when(mMockPackageManager
|
||||
.queryIntentActivitiesAsUser(any(Intent.class), eq(0), eq(0)))
|
||||
.queryIntentActivitiesAsUser(any(Intent.class), eq(0), eq(2)))
|
||||
.thenReturn(Arrays.asList(ri1, ri2));
|
||||
|
||||
// Setting the user should load the installed activities.
|
||||
mModel.setCurrentUser(0L);
|
||||
mModel.setCurrentUser(2);
|
||||
assertEquals(2, mModel.getAppCount());
|
||||
assertEquals("package1/class1", mModel.getApp(0).getComponentName().flattenToString());
|
||||
assertEquals(-1L, mModel.getApp(0).getUserSerialNumber());
|
||||
assertEquals(22L, mModel.getApp(0).getUserSerialNumber());
|
||||
assertEquals("package2/class2", mModel.getApp(1).getComponentName().flattenToString());
|
||||
assertEquals(-1L, mModel.getApp(1).getUserSerialNumber());
|
||||
assertEquals(22L, mModel.getApp(1).getUserSerialNumber());
|
||||
}
|
||||
|
||||
/** Tests initializing the model if one of the prefs is missing. */
|
||||
@@ -150,7 +146,7 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
|
||||
when(mMockPrefs.getString("22|app_1", null)).thenReturn(null);
|
||||
|
||||
// Initializing the model should load from prefs and skip the missing one.
|
||||
mModel.setCurrentUser(22L);
|
||||
mModel.setCurrentUser(2);
|
||||
assertEquals(1, mModel.getAppCount());
|
||||
assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
|
||||
assertEquals(239L, mModel.getApp(0).getUserSerialNumber());
|
||||
@@ -161,13 +157,11 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
|
||||
initializeModelFromPrefs();
|
||||
|
||||
mModel.savePrefs();
|
||||
verify(mMockEdit).putInt("22|app_count", 3);
|
||||
verify(mMockEdit).putString("22|app_0", "package0/class0");
|
||||
verify(mMockEdit).putLong("22|app_user_0", -1L);
|
||||
verify(mMockEdit).putString("22|app_1", "package1/class1");
|
||||
verify(mMockEdit).putLong("22|app_user_1", 45L);
|
||||
verify(mMockEdit).putString("22|app_2", "package2/class2");
|
||||
verify(mMockEdit).putLong("22|app_user_2", 239L);
|
||||
verify(mMockEdit).putInt("22|app_count", 2);
|
||||
verify(mMockEdit).putString("22|app_0", "package1/class1");
|
||||
verify(mMockEdit).putLong("22|app_user_0", 45L);
|
||||
verify(mMockEdit).putString("22|app_1", "package2/class2");
|
||||
verify(mMockEdit).putLong("22|app_user_1", 239L);
|
||||
verify(mMockEdit).apply();
|
||||
verifyNoMoreInteractions(mMockEdit);
|
||||
}
|
||||
@@ -179,7 +173,7 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
|
||||
|
||||
new NavigationBarAppsModel(getContext());
|
||||
verify(mMockEdit).clear();
|
||||
verify(mMockEdit).putInt("version", 2);
|
||||
verify(mMockEdit).putInt("version", 3);
|
||||
verify(mMockEdit).apply();
|
||||
verifyNoMoreInteractions(mMockEdit);
|
||||
}
|
||||
@@ -200,7 +194,7 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
|
||||
|
||||
// Assume the user's app count pref isn't available. This will trigger clearing deleted
|
||||
// users' prefs.
|
||||
when(mMockPrefs.getInt("0|app_count", -1)).thenReturn(-1);
|
||||
when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(-1);
|
||||
|
||||
final Map allPrefs = new HashMap<String, Object>();
|
||||
allPrefs.put("version", null);
|
||||
@@ -212,7 +206,7 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
|
||||
when(mMockPrefs.getAll()).thenReturn(allPrefs);
|
||||
|
||||
// Setting the user should remove prefs for deleted users.
|
||||
mModel.setCurrentUser(0L);
|
||||
mModel.setCurrentUser(2);
|
||||
verify(mMockEdit).remove("some_strange_pref");
|
||||
verify(mMockEdit).remove("");
|
||||
verify(mMockEdit).remove("|");
|
||||
|
||||
Reference in New Issue
Block a user