diff --git a/src/com/android/settings/location/RecentLocationApps.java b/src/com/android/settings/location/RecentLocationApps.java index 19df1158d01..164f4e71e7a 100644 --- a/src/com/android/settings/location/RecentLocationApps.java +++ b/src/com/android/settings/location/RecentLocationApps.java @@ -16,18 +16,15 @@ package com.android.settings.location; -import android.app.AppGlobals; +import android.app.ActivityManager; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.IPackageManager; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Process; -import android.os.RemoteException; import android.os.UserHandle; -import android.os.UserManager; import android.preference.Preference; import android.util.Log; @@ -92,37 +89,33 @@ public class RecentLocationApps { } /** - * Fills a list of applications which queried location recently within specified time. + * Fills a list of applications which queried location recently within + * specified time. */ public List getAppList() { // Retrieve a location usage list from AppOps AppOpsManager aoManager = (AppOpsManager) mActivity.getSystemService(Context.APP_OPS_SERVICE); - List appOps = aoManager.getPackagesForOps(new int[] { - AppOpsManager.OP_MONITOR_LOCATION, AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, }); + List appOps = aoManager.getPackagesForOps( + new int[] { + AppOpsManager.OP_MONITOR_LOCATION, + AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, + }); // Process the AppOps list and generate a preference list. ArrayList prefs = new ArrayList(); - final long now = System.currentTimeMillis(); - final UserManager um = (UserManager) mActivity.getSystemService(Context.USER_SERVICE); - final List profiles = um.getUserProfiles(); - - final int appOpsN = appOps.size(); - for (int i = 0; i < appOpsN; ++i) { - AppOpsManager.PackageOps ops = appOps.get(i); + long now = System.currentTimeMillis(); + for (AppOpsManager.PackageOps ops : appOps) { // Don't show the Android System in the list - it's not actionable for the user. - // Also don't show apps belonging to background users except managed users. - String packageName = ops.getPackageName(); + // Also don't show apps belonging to background users. int uid = ops.getUid(); - int userId = UserHandle.getUserId(uid); - boolean isAndroidOs = - (uid == Process.SYSTEM_UID) && ANDROID_SYSTEM_PACKAGE_NAME.equals(packageName); - if (isAndroidOs || !profiles.contains(UserHandle.fromUserId(userId))) { - continue; - } - Preference preference = getPreferenceFromOps(um, now, ops); - if (preference != null) { - prefs.add(preference); + boolean isAndroidOs = (uid == Process.SYSTEM_UID) + && ANDROID_SYSTEM_PACKAGE_NAME.equals(ops.getPackageName()); + if (!isAndroidOs && ActivityManager.getCurrentUser() == UserHandle.getUserId(uid)) { + Preference pref = getPreferenceFromOps(now, ops); + if (pref != null) { + prefs.add(pref); + } } } @@ -137,8 +130,7 @@ public class RecentLocationApps { * When the PackageOps is fresh enough, this method returns a Preference pointing to the App * Info page for that package. */ - private Preference getPreferenceFromOps(final UserManager um, long now, - AppOpsManager.PackageOps ops) { + private Preference getPreferenceFromOps(long now, AppOpsManager.PackageOps ops) { String packageName = ops.getPackageName(); List entries = ops.getOps(); boolean highBattery = false; @@ -169,24 +161,30 @@ public class RecentLocationApps { // The package is fresh enough, continue. - int uid = ops.getUid(); - int userId = UserHandle.getUserId(uid); - - Preference preference = null; + Preference pref = null; try { - IPackageManager ipm = AppGlobals.getPackageManager(); - ApplicationInfo appInfo = - ipm.getApplicationInfo(packageName, PackageManager.GET_META_DATA, userId); - - Drawable icon = um.getBadgedDrawableForUser( - mPackageManager.getApplicationIcon(appInfo), UserHandle.fromUserId(userId)); - preference = createRecentLocationEntry(icon, - mPackageManager.getApplicationLabel(appInfo), highBattery, - new PackageEntryClickedListener(packageName)); - } catch (RemoteException e) { - Log.w(TAG, "Error while retrieving application info", e); + ApplicationInfo appInfo = mPackageManager.getApplicationInfo( + packageName, PackageManager.GET_META_DATA); + // Multiple users can install the same package. Each user gets a different Uid for + // the same package. + // + // Here we retrieve the Uid with package name, that will be the Uid for that package + // associated with the current active user. If the Uid differs from the Uid in ops, + // that means this entry belongs to another inactive user and we should ignore that. + if (appInfo.uid == ops.getUid()) { + pref = createRecentLocationEntry( + mPackageManager.getApplicationIcon(appInfo), + mPackageManager.getApplicationLabel(appInfo), + highBattery, + new PackageEntryClickedListener(packageName)); + } else if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "package " + packageName + " with Uid " + ops.getUid() + + " belongs to another inactive account, ignored."); + } + } catch (PackageManager.NameNotFoundException e) { + Log.wtf(TAG, "Package not found: " + packageName, e); } - return preference; + return pref; } }