Merge profiles apps into app list

Remove the spinner and add all apps into one list and badge the managed
items.

Bug: 19443900
Change-Id: I9ccacc1b503da2663b9a3945f4fd6051ae95e328
This commit is contained in:
Jason Monk
2015-02-26 16:19:34 -05:00
parent 588a0881c1
commit 0702589168
6 changed files with 162 additions and 95 deletions

View File

@@ -25,11 +25,6 @@
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/default_preference_background"> android:background="@drawable/default_preference_background">
<FrameLayout android:id="@+id/pinned_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
<android.support.v4.view.ViewPager <android.support.v4.view.ViewPager
android:id="@+id/pager" android:id="@+id/pager"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -30,6 +30,7 @@ import android.hardware.usb.IUsbManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.util.Log; import android.util.Log;
@@ -53,6 +54,7 @@ public abstract class AppInfoBase extends PreferenceFragment
private ApplicationsState.Session mSession; private ApplicationsState.Session mSession;
protected ApplicationsState.AppEntry mAppEntry; protected ApplicationsState.AppEntry mAppEntry;
protected PackageInfo mPackageInfo; protected PackageInfo mPackageInfo;
protected int mUserId;
protected String mPackageName; protected String mPackageName;
protected IUsbManager mUsbManager; protected IUsbManager mUsbManager;
@@ -115,7 +117,8 @@ public abstract class AppInfoBase extends PreferenceFragment
mPackageName = intent.getData().getSchemeSpecificPart(); mPackageName = intent.getData().getSchemeSpecificPart();
} }
} }
mAppEntry = mState.getEntry(mPackageName); mUserId = UserHandle.myUserId();
mAppEntry = mState.getEntry(mPackageName, mUserId);
if (mAppEntry != null) { if (mAppEntry != null) {
// Get application info again to refresh changed properties of application // Get application info again to refresh changed properties of application
try { try {

View File

@@ -345,7 +345,7 @@ public class AppStorageSettings extends AppInfoWithHeader implements OnClickList
if (result == PackageManager.MOVE_SUCCEEDED) { if (result == PackageManager.MOVE_SUCCEEDED) {
Log.i(TAG, "Moved resources for " + packageName); Log.i(TAG, "Moved resources for " + packageName);
// Refresh size information again. // Refresh size information again.
mState.requestSize(mAppEntry.info.packageName); mState.requestSize(mPackageName, mUserId);
} else { } else {
showDialogInner(DLG_MOVE_FAILED, result); showDialogInner(DLG_MOVE_FAILED, result);
} }
@@ -362,7 +362,7 @@ public class AppStorageSettings extends AppInfoWithHeader implements OnClickList
mClearDataButton.setText(R.string.clear_user_data_text); mClearDataButton.setText(R.string.clear_user_data_text);
if(result == OP_SUCCESSFUL) { if(result == OP_SUCCESSFUL) {
Log.i(TAG, "Cleared user data for package : "+packageName); Log.i(TAG, "Cleared user data for package : "+packageName);
mState.requestSize(mAppEntry.info.packageName); mState.requestSize(mPackageName, mUserId);
} else { } else {
mClearDataButton.setEnabled(true); mClearDataButton.setEnabled(true);
} }
@@ -443,7 +443,7 @@ public class AppStorageSettings extends AppInfoWithHeader implements OnClickList
break; break;
case MSG_CLEAR_CACHE: case MSG_CLEAR_CACHE:
// Refresh size info // Refresh size info
mState.requestSize(mPackageName); mState.requestSize(mPackageName, mUserId);
break; break;
case MSG_PACKAGE_MOVE: case MSG_PACKAGE_MOVE:
processMoveMsg(msg); processMoveMsg(msg);

View File

@@ -1,15 +1,18 @@
package com.android.settings.applications; package com.android.settings.applications;
import android.app.AppGlobals;
import android.app.Application; import android.app.Application;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.IPackageStatsObserver; import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageStats; import android.content.pm.PackageStats;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
@@ -17,10 +20,13 @@ import android.os.HandlerThread;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.Process; import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager;
import android.text.format.Formatter; import android.text.format.Formatter;
import android.util.Log; import android.util.Log;
import android.util.SparseArray;
import java.io.File; import java.io.File;
import java.text.Collator; import java.text.Collator;
@@ -140,7 +146,7 @@ public class ApplicationsState {
boolean ensureIconLocked(Context context, PackageManager pm) { boolean ensureIconLocked(Context context, PackageManager pm) {
if (this.icon == null) { if (this.icon == null) {
if (this.apkFile.exists()) { if (this.apkFile.exists()) {
this.icon = this.info.loadIcon(pm); this.icon = getBadgedIcon(pm);
return true; return true;
} else { } else {
this.mounted = false; this.mounted = false;
@@ -152,12 +158,18 @@ public class ApplicationsState {
// its icon. // its icon.
if (this.apkFile.exists()) { if (this.apkFile.exists()) {
this.mounted = true; this.mounted = true;
this.icon = this.info.loadIcon(pm); this.icon = getBadgedIcon(pm);
return true; return true;
} }
} }
return false; return false;
} }
private Drawable getBadgedIcon(PackageManager pm) {
// Do badging ourself so that it comes from the user of the app not the current user.
return pm.getUserBadgedIcon(pm.loadUnbadgedItemIcon(info, info),
new UserHandle(UserHandle.getUserId(info.uid)));
}
} }
public static final Comparator<AppEntry> ALPHA_COMPARATOR = new Comparator<AppEntry>() { public static final Comparator<AppEntry> ALPHA_COMPARATOR = new Comparator<AppEntry>() {
@@ -265,6 +277,8 @@ public class ApplicationsState {
final Context mContext; final Context mContext;
final PackageManager mPm; final PackageManager mPm;
final IPackageManager mIpm;
final UserManager mUm;
final int mRetrieveFlags; final int mRetrieveFlags;
PackageIntentReceiver mPackageIntentReceiver; PackageIntentReceiver mPackageIntentReceiver;
@@ -276,11 +290,14 @@ public class ApplicationsState {
final ArrayList<Session> mSessions = new ArrayList<Session>(); final ArrayList<Session> mSessions = new ArrayList<Session>();
final ArrayList<Session> mRebuildingSessions = new ArrayList<Session>(); final ArrayList<Session> mRebuildingSessions = new ArrayList<Session>();
final InterestingConfigChanges mInterestingConfigChanges = new InterestingConfigChanges(); final InterestingConfigChanges mInterestingConfigChanges = new InterestingConfigChanges();
final HashMap<String, AppEntry> mEntriesMap = new HashMap<String, AppEntry>(); // Map: userid => (Map: package name => AppEntry)
final SparseArray<HashMap<String, AppEntry>> mEntriesMap =
new SparseArray<HashMap<String, AppEntry>>();
final ArrayList<AppEntry> mAppEntries = new ArrayList<AppEntry>(); final ArrayList<AppEntry> mAppEntries = new ArrayList<AppEntry>();
List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>(); List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>();
long mCurId = 1; long mCurId = 1;
String mCurComputingSizePkg; String mCurComputingSizePkg;
int mCurComputingSizeUserId;
boolean mSessionsChanged; boolean mSessionsChanged;
// Temporary for dispatching session callbacks. Only touched by main thread. // Temporary for dispatching session callbacks. Only touched by main thread.
@@ -301,6 +318,11 @@ public class ApplicationsState {
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(this, sdFilter); mContext.registerReceiver(this, sdFilter);
// Register for events related to user creation/deletion.
IntentFilter userFilter = new IntentFilter();
userFilter.addAction(Intent.ACTION_USER_ADDED);
userFilter.addAction(Intent.ACTION_USER_REMOVED);
mContext.registerReceiver(this, userFilter);
} }
void unregisterReceiver() { void unregisterReceiver() {
mContext.unregisterReceiver(this); mContext.unregisterReceiver(this);
@@ -311,15 +333,21 @@ public class ApplicationsState {
if (Intent.ACTION_PACKAGE_ADDED.equals(actionStr)) { if (Intent.ACTION_PACKAGE_ADDED.equals(actionStr)) {
Uri data = intent.getData(); Uri data = intent.getData();
String pkgName = data.getEncodedSchemeSpecificPart(); String pkgName = data.getEncodedSchemeSpecificPart();
addPackage(pkgName); for (int i = 0; i < mEntriesMap.size(); i++) {
addPackage(pkgName, mEntriesMap.keyAt(i));
}
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(actionStr)) { } else if (Intent.ACTION_PACKAGE_REMOVED.equals(actionStr)) {
Uri data = intent.getData(); Uri data = intent.getData();
String pkgName = data.getEncodedSchemeSpecificPart(); String pkgName = data.getEncodedSchemeSpecificPart();
removePackage(pkgName); for (int i = 0; i < mEntriesMap.size(); i++) {
removePackage(pkgName, mEntriesMap.keyAt(i));
}
} else if (Intent.ACTION_PACKAGE_CHANGED.equals(actionStr)) { } else if (Intent.ACTION_PACKAGE_CHANGED.equals(actionStr)) {
Uri data = intent.getData(); Uri data = intent.getData();
String pkgName = data.getEncodedSchemeSpecificPart(); String pkgName = data.getEncodedSchemeSpecificPart();
invalidatePackage(pkgName); for (int i = 0; i < mEntriesMap.size(); i++) {
invalidatePackage(pkgName, mEntriesMap.keyAt(i));
}
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr) || } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr) ||
Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(actionStr)) { Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(actionStr)) {
// When applications become available or unavailable (perhaps because // When applications become available or unavailable (perhaps because
@@ -336,9 +364,15 @@ public class ApplicationsState {
boolean avail = Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr); boolean avail = Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr);
if (avail) { if (avail) {
for (String pkgName : pkgList) { for (String pkgName : pkgList) {
invalidatePackage(pkgName); for (int i = 0; i < mEntriesMap.size(); i++) {
invalidatePackage(pkgName, mEntriesMap.keyAt(i));
}
} }
} }
} else if (Intent.ACTION_USER_ADDED.equals(actionStr)) {
addUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL));
} else if (Intent.ACTION_USER_REMOVED.equals(actionStr)) {
removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL));
} }
} }
} }
@@ -426,6 +460,11 @@ public class ApplicationsState {
private ApplicationsState(Application app) { private ApplicationsState(Application app) {
mContext = app; mContext = app;
mPm = mContext.getPackageManager(); mPm = mContext.getPackageManager();
mIpm = AppGlobals.getPackageManager();
mUm = (UserManager) app.getSystemService(Context.USER_SERVICE);
for (UserHandle user : mUm.getUserProfiles()) {
mEntriesMap.put(user.getIdentifier(), new HashMap<String, AppEntry>());
}
mThread = new HandlerThread("ApplicationsState.Loader", mThread = new HandlerThread("ApplicationsState.Loader",
Process.THREAD_PRIORITY_BACKGROUND); Process.THREAD_PRIORITY_BACKGROUND);
mThread.start(); mThread.start();
@@ -630,15 +669,22 @@ public class ApplicationsState {
mPackageIntentReceiver = new PackageIntentReceiver(); mPackageIntentReceiver = new PackageIntentReceiver();
mPackageIntentReceiver.registerReceiver(); mPackageIntentReceiver.registerReceiver();
} }
mApplications = mPm.getInstalledApplications(mRetrieveFlags); mApplications = new ArrayList<ApplicationInfo>();
if (mApplications == null) { for (UserHandle user : mUm.getUserProfiles()) {
mApplications = new ArrayList<ApplicationInfo>(); try {
ParceledListSlice<ApplicationInfo> list =
mIpm.getInstalledApplications(mRetrieveFlags, user.getIdentifier());
mApplications.addAll(list.getList());
} catch (RemoteException e) {
}
} }
if (mInterestingConfigChanges.applyNewConfig(mContext.getResources())) { if (mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
// If an interesting part of the configuration has changed, we // If an interesting part of the configuration has changed, we
// should completely reload the app entries. // should completely reload the app entries.
mEntriesMap.clear(); for (int i = 0; i < mEntriesMap.size(); i++) {
mEntriesMap.valueAt(i).clear();
}
mAppEntries.clear(); mAppEntries.clear();
} else { } else {
for (int i=0; i<mAppEntries.size(); i++) { for (int i=0; i<mAppEntries.size(); i++) {
@@ -659,7 +705,8 @@ public class ApplicationsState {
} }
mHaveDisabledApps = true; mHaveDisabledApps = true;
} }
final AppEntry entry = mEntriesMap.get(info.packageName); int userId = UserHandle.getUserId(info.uid);
final AppEntry entry = mEntriesMap.get(userId).get(info.packageName);
if (entry != null) { if (entry != null) {
entry.info = info; entry.info = info;
} }
@@ -683,6 +730,10 @@ public class ApplicationsState {
return; return;
} }
} }
doPauseLocked();
}
void doPauseLocked() {
mResumed = false; mResumed = false;
if (mPackageIntentReceiver != null) { if (mPackageIntentReceiver != null) {
mPackageIntentReceiver.unregisterReceiver(); mPackageIntentReceiver.unregisterReceiver();
@@ -690,10 +741,10 @@ public class ApplicationsState {
} }
} }
AppEntry getEntry(String packageName) { AppEntry getEntry(String packageName, int userId) {
if (DEBUG_LOCKING) Log.v(TAG, "getEntry about to acquire lock..."); if (DEBUG_LOCKING) Log.v(TAG, "getEntry about to acquire lock...");
synchronized (mEntriesMap) { synchronized (mEntriesMap) {
AppEntry entry = mEntriesMap.get(packageName); AppEntry entry = mEntriesMap.get(userId).get(packageName);
if (entry == null) { if (entry == null) {
for (int i=0; i<mApplications.size(); i++) { for (int i=0; i<mApplications.size(); i++) {
ApplicationInfo info = mApplications.get(i); ApplicationInfo info = mApplications.get(i);
@@ -717,12 +768,12 @@ public class ApplicationsState {
} }
} }
void requestSize(String packageName) { void requestSize(String packageName, int userId) {
if (DEBUG_LOCKING) Log.v(TAG, "requestSize about to acquire lock..."); if (DEBUG_LOCKING) Log.v(TAG, "requestSize about to acquire lock...");
synchronized (mEntriesMap) { synchronized (mEntriesMap) {
AppEntry entry = mEntriesMap.get(packageName); AppEntry entry = mEntriesMap.get(userId).get(packageName);
if (entry != null) { if (entry != null) {
mPm.getPackageSizeInfo(packageName, mBackgroundHandler.mStatsObserver); mPm.getPackageSizeInfo(packageName, userId, mBackgroundHandler.mStatsObserver);
} }
if (DEBUG_LOCKING) Log.v(TAG, "...requestSize releasing lock"); if (DEBUG_LOCKING) Log.v(TAG, "...requestSize releasing lock");
} }
@@ -741,16 +792,18 @@ public class ApplicationsState {
return sum; return sum;
} }
int indexOfApplicationInfoLocked(String pkgName) { int indexOfApplicationInfoLocked(String pkgName, int userId) {
for (int i=mApplications.size()-1; i>=0; i--) { for (int i=mApplications.size()-1; i>=0; i--) {
if (mApplications.get(i).packageName.equals(pkgName)) { ApplicationInfo appInfo = mApplications.get(i);
if (appInfo.packageName.equals(pkgName)
&& UserHandle.getUserId(appInfo.uid) == userId) {
return i; return i;
} }
} }
return -1; return -1;
} }
void addPackage(String pkgName) { void addPackage(String pkgName, int userId) {
try { try {
synchronized (mEntriesMap) { synchronized (mEntriesMap) {
if (DEBUG_LOCKING) Log.v(TAG, "addPackage acquired lock"); if (DEBUG_LOCKING) Log.v(TAG, "addPackage acquired lock");
@@ -762,12 +815,15 @@ public class ApplicationsState {
if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: not resumed"); if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: not resumed");
return; return;
} }
if (indexOfApplicationInfoLocked(pkgName) >= 0) { if (indexOfApplicationInfoLocked(pkgName, userId) >= 0) {
if (DEBUG) Log.i(TAG, "Package already exists!"); if (DEBUG) Log.i(TAG, "Package already exists!");
if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: already exists"); if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: already exists");
return; return;
} }
ApplicationInfo info = mPm.getApplicationInfo(pkgName, mRetrieveFlags); ApplicationInfo info = mIpm.getApplicationInfo(pkgName, mRetrieveFlags, userId);
if (info == null) {
return;
}
if (!info.enabled) { if (!info.enabled) {
if (info.enabledSetting if (info.enabledSetting
!= PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
@@ -784,20 +840,20 @@ public class ApplicationsState {
} }
if (DEBUG_LOCKING) Log.v(TAG, "addPackage releasing lock"); if (DEBUG_LOCKING) Log.v(TAG, "addPackage releasing lock");
} }
} catch (NameNotFoundException e) { } catch (RemoteException e) {
} }
} }
void removePackage(String pkgName) { void removePackage(String pkgName, int userId) {
synchronized (mEntriesMap) { synchronized (mEntriesMap) {
if (DEBUG_LOCKING) Log.v(TAG, "removePackage acquired lock"); if (DEBUG_LOCKING) Log.v(TAG, "removePackage acquired lock");
int idx = indexOfApplicationInfoLocked(pkgName); int idx = indexOfApplicationInfoLocked(pkgName, userId);
if (DEBUG) Log.i(TAG, "removePackage: " + pkgName + " @ " + idx); if (DEBUG) Log.i(TAG, "removePackage: " + pkgName + " @ " + idx);
if (idx >= 0) { if (idx >= 0) {
AppEntry entry = mEntriesMap.get(pkgName); AppEntry entry = mEntriesMap.get(userId).get(pkgName);
if (DEBUG) Log.i(TAG, "removePackage: " + entry); if (DEBUG) Log.i(TAG, "removePackage: " + entry);
if (entry != null) { if (entry != null) {
mEntriesMap.remove(pkgName); mEntriesMap.get(userId).remove(pkgName);
mAppEntries.remove(entry); mAppEntries.remove(entry);
} }
ApplicationInfo info = mApplications.get(idx); ApplicationInfo info = mApplications.get(idx);
@@ -819,18 +875,53 @@ public class ApplicationsState {
} }
} }
void invalidatePackage(String pkgName) { void invalidatePackage(String pkgName, int userId) {
removePackage(pkgName); removePackage(pkgName, userId);
addPackage(pkgName); addPackage(pkgName, userId);
} }
void addUser(int userId) {
if (mUm.getUserProfiles().contains(new UserHandle(userId))) {
synchronized (mEntriesMap) {
mEntriesMap.put(userId, new HashMap<String, AppEntry>());
if (mResumed) {
// If resumed, Manually pause, then cause a resume to repopulate the app list.
// This is the simplest way to reload the packages so that the new user
// is included. Otherwise the list will be repopulated on next resume.
doPauseLocked();
doResumeIfNeededLocked();
}
if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_LIST_CHANGED)) {
mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_LIST_CHANGED);
}
}
}
}
void removeUser(int userId) {
synchronized (mEntriesMap) {
HashMap<String, AppEntry> userMap = mEntriesMap.get(userId);
if (userMap != null) {
for (AppEntry appEntry : userMap.values()) {
mAppEntries.remove(appEntry);
mApplications.remove(appEntry.info);
}
mEntriesMap.remove(userId);
if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_LIST_CHANGED)) {
mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_LIST_CHANGED);
}
}
}
}
AppEntry getEntryLocked(ApplicationInfo info) { AppEntry getEntryLocked(ApplicationInfo info) {
AppEntry entry = mEntriesMap.get(info.packageName); int userId = UserHandle.getUserId(info.uid);
AppEntry entry = mEntriesMap.get(userId).get(info.packageName);
if (DEBUG) Log.i(TAG, "Looking up entry of pkg " + info.packageName + ": " + entry); if (DEBUG) Log.i(TAG, "Looking up entry of pkg " + info.packageName + ": " + entry);
if (entry == null) { if (entry == null) {
if (DEBUG) Log.i(TAG, "Creating AppEntry for " + info.packageName); if (DEBUG) Log.i(TAG, "Creating AppEntry for " + info.packageName);
entry = new AppEntry(mContext, info, mCurId++); entry = new AppEntry(mContext, info, mCurId++);
mEntriesMap.put(info.packageName, entry); mEntriesMap.get(userId).put(info.packageName, entry);
mAppEntries.add(entry); mAppEntries.add(entry);
} else if (entry.info != info) { } else if (entry.info != info) {
entry.info = info; entry.info = info;
@@ -880,7 +971,12 @@ public class ApplicationsState {
boolean sizeChanged = false; boolean sizeChanged = false;
synchronized (mEntriesMap) { synchronized (mEntriesMap) {
if (DEBUG_LOCKING) Log.v(TAG, "onGetStatsCompleted acquired lock"); if (DEBUG_LOCKING) Log.v(TAG, "onGetStatsCompleted acquired lock");
AppEntry entry = mEntriesMap.get(stats.packageName); HashMap<String, AppEntry> userMap = mEntriesMap.get(stats.userHandle);
if (userMap == null) {
// The user must have been removed.
return;
}
AppEntry entry = userMap.get(stats.packageName);
if (entry != null) { if (entry != null) {
synchronized (entry) { synchronized (entry) {
entry.sizeStale = false; entry.sizeStale = false;
@@ -922,7 +1018,8 @@ public class ApplicationsState {
} }
} }
if (mCurComputingSizePkg == null if (mCurComputingSizePkg == null
|| mCurComputingSizePkg.equals(stats.packageName)) { || (mCurComputingSizePkg.equals(stats.packageName)
&& mCurComputingSizeUserId == stats.userHandle)) {
mCurComputingSizePkg = null; mCurComputingSizePkg = null;
sendEmptyMessage(MSG_LOAD_SIZES); sendEmptyMessage(MSG_LOAD_SIZES);
} }
@@ -966,7 +1063,8 @@ public class ApplicationsState {
mMainHandler.sendMessage(m); mMainHandler.sendMessage(m);
} }
ApplicationInfo info = mApplications.get(i); ApplicationInfo info = mApplications.get(i);
if (mEntriesMap.get(info.packageName) == null) { int userId = UserHandle.getUserId(info.uid);
if (mEntriesMap.get(userId).get(info.packageName) == null) {
numDone++; numDone++;
getEntryLocked(info); getEntryLocked(info);
} }
@@ -1035,7 +1133,9 @@ public class ApplicationsState {
} }
entry.sizeLoadStart = now; entry.sizeLoadStart = now;
mCurComputingSizePkg = entry.info.packageName; mCurComputingSizePkg = entry.info.packageName;
mPm.getPackageSizeInfo(mCurComputingSizePkg, mStatsObserver); mCurComputingSizeUserId = UserHandle.getUserId(entry.info.uid);
mPm.getPackageSizeInfo(mCurComputingSizePkg,
mCurComputingSizeUserId, mStatsObserver);
} }
if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing: now computing"); if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing: now computing");
return; return;

View File

@@ -482,8 +482,9 @@ public class InstalledAppDetails extends AppInfoBase
ActivityManager am = (ActivityManager)getActivity().getSystemService( ActivityManager am = (ActivityManager)getActivity().getSystemService(
Context.ACTIVITY_SERVICE); Context.ACTIVITY_SERVICE);
am.forceStopPackage(pkgName); am.forceStopPackage(pkgName);
mState.invalidatePackage(pkgName); int userId = UserHandle.getUserId(mAppEntry.info.uid);
ApplicationsState.AppEntry newEnt = mState.getEntry(pkgName); mState.invalidatePackage(pkgName, userId);
ApplicationsState.AppEntry newEnt = mState.getEntry(pkgName, userId);
if (newEnt != null) { if (newEnt != null) {
mAppEntry = newEnt; mAppEntry = newEnt;
} }

View File

@@ -35,6 +35,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.NetworkPolicyManager; import android.net.NetworkPolicyManager;
import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
@@ -70,13 +71,12 @@ import android.widget.Spinner;
import com.android.internal.app.IMediaContainerService; import com.android.internal.app.IMediaContainerService;
import com.android.internal.content.PackageHelper; import com.android.internal.content.PackageHelper;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.UserSpinnerAdapter;
import com.android.settings.Settings.RunningServicesActivity; import com.android.settings.Settings.RunningServicesActivity;
import com.android.settings.Settings.StorageUseActivity; import com.android.settings.Settings.StorageUseActivity;
import com.android.settings.UserSpinnerAdapter;
import com.android.settings.Utils;
import com.android.settings.applications.ApplicationsState.AppEntry; import com.android.settings.applications.ApplicationsState.AppEntry;
import com.android.settings.deviceinfo.StorageMeasurement; import com.android.settings.deviceinfo.StorageMeasurement;
import com.android.settings.Utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
@@ -135,8 +135,7 @@ interface AppClickListener {
* intent. * intent.
*/ */
public class ManageApplications extends Fragment implements public class ManageApplications extends Fragment implements
AppClickListener, DialogInterface.OnClickListener, AppClickListener, DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
DialogInterface.OnDismissListener, OnItemSelectedListener {
static final String TAG = "ManageApplications"; static final String TAG = "ManageApplications";
static final boolean DEBUG = false; static final boolean DEBUG = false;
@@ -451,6 +450,7 @@ public class ManageApplications extends Fragment implements
private LayoutInflater mInflater; private LayoutInflater mInflater;
private String mCurrentPkgName; private String mCurrentPkgName;
private int mCurrentUid;
private Menu mOptionsMenu; private Menu mOptionsMenu;
@@ -472,7 +472,6 @@ public class ManageApplications extends Fragment implements
private View mRootView; private View mRootView;
private ViewPager mViewPager; private ViewPager mViewPager;
private ViewGroup mPinnedHeader; private ViewGroup mPinnedHeader;
private UserSpinnerAdapter mProfileSpinnerAdapter;
private Spinner mSpinner; private Spinner mSpinner;
private Context mContext; private Context mContext;
@@ -911,9 +910,6 @@ public class ManageApplications extends Fragment implements
mTabs.add(tab); mTabs.add(tab);
mNumTabs = mTabs.size(); mNumTabs = mTabs.size();
final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mProfileSpinnerAdapter = Utils.createUserSpinnerAdapter(um, mContext);
} }
@@ -926,14 +922,6 @@ public class ManageApplications extends Fragment implements
container, false); container, false);
mContentContainer = container; mContentContainer = container;
mRootView = rootView; mRootView = rootView;
mPinnedHeader = (ViewGroup) mRootView.findViewById(R.id.pinned_header);
if (mProfileSpinnerAdapter != null) {
mSpinner = (Spinner) inflater.inflate(R.layout.spinner_view, null);
mSpinner.setAdapter(mProfileSpinnerAdapter);
mSpinner.setOnItemSelectedListener(this);
mPinnedHeader.addView(mSpinner);
mPinnedHeader.setVisibility(View.VISIBLE);
}
mViewPager = (ViewPager) rootView.findViewById(R.id.pager); mViewPager = (ViewPager) rootView.findViewById(R.id.pager);
MyPagerAdapter adapter = new MyPagerAdapter(); MyPagerAdapter adapter = new MyPagerAdapter();
mViewPager.setAdapter(adapter); mViewPager.setAdapter(adapter);
@@ -1029,31 +1017,10 @@ public class ManageApplications extends Fragment implements
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) { if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
mApplicationsState.requestSize(mCurrentPkgName); mApplicationsState.requestSize(mCurrentPkgName, UserHandle.getUserId(mCurrentUid));
} }
} }
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
UserHandle selectedUser = mProfileSpinnerAdapter.getUserHandle(position);
if (selectedUser.getIdentifier() != UserHandle.myUserId()) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
int currentTab = mViewPager.getCurrentItem();
intent.putExtra(EXTRA_LIST_TYPE, mTabs.get(currentTab).mListType);
mContext.startActivityAsUser(intent, selectedUser);
// Go back to default selection, which is the first one; this makes sure that pressing
// the back button takes you into a consistent state
mSpinner.setSelection(0);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Nothing to do
}
private void updateNumTabs() { private void updateNumTabs() {
int newNum = mApplicationsState.haveDisabledApps() ? mTabs.size() : (mTabs.size()-1); int newNum = mApplicationsState.haveDisabledApps() ? mTabs.size() : (mTabs.size()-1);
if (newNum != mNumTabs) { if (newNum != mNumTabs) {
@@ -1076,13 +1043,13 @@ public class ManageApplications extends Fragment implements
// utility method used to start sub activity // utility method used to start sub activity
private void startApplicationDetailsActivity() { private void startApplicationDetailsActivity() {
// start new fragment to display extended information // TODO: Figure out if there is a way where we can spin up the profile's settings
Bundle args = new Bundle(); // process ahead of time, to avoid a long load of data when user clicks on a managed app.
args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mCurrentPkgName); // Maybe when they load the list of apps that contains managed profile apps.
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
SettingsActivity sa = (SettingsActivity) getActivity(); intent.setData(Uri.fromParts("package", mCurrentPkgName, null));
sa.startPreferencePanel(InstalledAppDetails.class.getName(), args, getActivity().startActivityAsUser(intent,
R.string.application_info_label, null, this, INSTALLED_APP_DETAILS); new UserHandle(UserHandle.getUserId(mCurrentUid)));
} }
@Override @Override
@@ -1273,6 +1240,7 @@ public class ManageApplications extends Fragment implements
if (tab.mApplications != null && tab.mApplications.getCount() > position) { if (tab.mApplications != null && tab.mApplications.getCount() > position) {
ApplicationsState.AppEntry entry = tab.mApplications.getAppEntry(position); ApplicationsState.AppEntry entry = tab.mApplications.getAppEntry(position);
mCurrentPkgName = entry.info.packageName; mCurrentPkgName = entry.info.packageName;
mCurrentUid = entry.info.uid;
startApplicationDetailsActivity(); startApplicationDetailsActivity();
} }
} }