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:
@@ -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"
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user