diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e3a7e969149..d1b09cb5f43 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -4,6 +4,9 @@
coreApp="true"
android:sharedUserId="android.uid.system">
+
+
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index b7f62a300d7..21a5019f039 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -16,8 +16,6 @@
package com.android.settings;
-import static android.content.Intent.EXTRA_USER;
-
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -70,8 +68,6 @@ import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
import android.service.persistentdata.PersistentDataBlockManager;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -87,20 +83,21 @@ import android.widget.TabWidget;
import com.android.internal.util.UserIcons;
import com.android.settings.UserAdapter.UserDetails;
-import com.android.settings.applications.ApplicationsState;
import com.android.settings.dashboard.DashboardTile;
import com.android.settings.drawable.CircleFramedDrawable;
+import com.android.settingslib.applications.ApplicationsState;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.text.NumberFormat;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
+import static android.content.Intent.EXTRA_USER;
+
public final class Utils {
private static final String TAG = "Settings";
diff --git a/src/com/android/settings/applications/AdvancedAppSettings.java b/src/com/android/settings/applications/AdvancedAppSettings.java
index f407cb15801..c2966fe6b0d 100644
--- a/src/com/android/settings/applications/AdvancedAppSettings.java
+++ b/src/com/android/settings/applications/AdvancedAppSettings.java
@@ -23,10 +23,11 @@ import android.preference.Preference;
import com.android.internal.logging.MetricsLogger;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.applications.ApplicationsState.AppEntry;
-import com.android.settings.applications.ApplicationsState.Session;
import com.android.settings.applications.PermissionsSummaryHelper.PermissionsResultCallback;
import com.android.settings.fuelgauge.PowerWhitelistBackend;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.Session;
import java.util.ArrayList;
diff --git a/src/com/android/settings/applications/AppInfoBase.java b/src/com/android/settings/applications/AppInfoBase.java
index 6dbeefd8b6d..ff618c2a200 100644
--- a/src/com/android/settings/applications/AppInfoBase.java
+++ b/src/com/android/settings/applications/AppInfoBase.java
@@ -38,7 +38,8 @@ import android.util.Log;
import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
-import com.android.settings.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
import java.util.ArrayList;
diff --git a/src/com/android/settings/applications/AppPermissionSettings.java b/src/com/android/settings/applications/AppPermissionSettings.java
deleted file mode 100644
index 16757d91545..00000000000
--- a/src/com/android/settings/applications/AppPermissionSettings.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AppSecurityPermissions;
-import android.widget.ArrayAdapter;
-import android.widget.LinearLayout;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.telephony.ISms;
-import com.android.internal.telephony.SmsUsageMonitor;
-import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.applications.ApplicationsState.AppEntry;
-
-import java.util.ArrayList;
-
-public class AppPermissionSettings extends AppInfoWithHeader {
-
- private ISms mSmsManager;
- private View mRootView;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mSmsManager = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- final View view = inflater.inflate(R.layout.permission_settings, container, false);
-
- final ViewGroup allDetails = (ViewGroup) view.findViewById(R.id.all_details);
- Utils.forceCustomPadding(allDetails, true /* additive padding */);
-
- mRootView = view;
- return view;
- }
-
- @Override
- protected boolean refreshUi() {
- retrieveAppEntry();
- // Security permissions section
- LinearLayout permsView = (LinearLayout) mRootView.findViewById(R.id.permissions_section);
- AppSecurityPermissions asp = new AppSecurityPermissions(getActivity(), mPackageName);
- int premiumSmsPermission = getPremiumSmsPermission(mPackageName);
- // Premium SMS permission implies the app also has SEND_SMS permission, so the original
- // application permissions list doesn't have to be shown/hidden separately. The premium
- // SMS subsection should only be visible if the app has tried to send to a premium SMS.
- if (asp.getPermissionCount() > 0
- || premiumSmsPermission != SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN) {
- permsView.setVisibility(View.VISIBLE);
- } else {
- permsView.setVisibility(View.GONE);
- }
- // Premium SMS permission subsection
- TextView securityBillingDesc = (TextView) permsView.findViewById(
- R.id.security_settings_billing_desc);
- LinearLayout securityBillingList = (LinearLayout) permsView.findViewById(
- R.id.security_settings_billing_list);
- if (premiumSmsPermission != SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN) {
- // Show the premium SMS permission selector
- securityBillingDesc.setVisibility(View.VISIBLE);
- securityBillingList.setVisibility(View.VISIBLE);
- Spinner spinner = (Spinner) permsView.findViewById(
- R.id.security_settings_premium_sms_list);
- ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),
- R.array.security_settings_premium_sms_values,
- android.R.layout.simple_spinner_item);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- spinner.setAdapter(adapter);
- // List items are in the same order as SmsUsageMonitor constants, offset by 1.
- spinner.setSelection(premiumSmsPermission - 1);
- spinner.setOnItemSelectedListener(new PremiumSmsSelectionListener(
- mPackageName, mSmsManager));
- } else {
- // Hide the premium SMS permission selector
- securityBillingDesc.setVisibility(View.GONE);
- securityBillingList.setVisibility(View.GONE);
- }
- // App permissions subsection
- if (asp.getPermissionCount() > 0) {
- // Make the security sections header visible
- LinearLayout securityList = (LinearLayout) permsView.findViewById(
- R.id.security_settings_list);
- securityList.removeAllViews();
- securityList.addView(asp.getPermissionsViewWithRevokeButtons());
- // If this app is running under a shared user ID with other apps,
- // update the description to explain this.
- String[] packages = mPm.getPackagesForUid(mPackageInfo.applicationInfo.uid);
- if (packages != null && packages.length > 1) {
- ArrayList pnames = new ArrayList();
- for (int i=0; i 0) {
- final Resources res = getActivity().getResources();
- String appListStr;
- if (N == 1) {
- appListStr = pnames.get(0).toString();
- } else if (N == 2) {
- appListStr = res.getString(R.string.join_two_items, pnames.get(0),
- pnames.get(1));
- } else {
- appListStr = pnames.get(N-2).toString();
- for (int i=N-3; i>=0; i--) {
- appListStr = res.getString(i == 0 ? R.string.join_many_items_first
- : R.string.join_many_items_middle, pnames.get(i), appListStr);
- }
- appListStr = res.getString(R.string.join_many_items_last,
- appListStr, pnames.get(N-1));
- }
- TextView descr = (TextView) mRootView.findViewById(
- R.id.security_settings_desc);
- descr.setText(res.getString(R.string.security_settings_desc_multi,
- mPackageInfo.applicationInfo.loadLabel(mPm), appListStr));
- }
- }
- }
- return true;
- }
-
- private int getPremiumSmsPermission(String packageName) {
- try {
- if (mSmsManager != null) {
- return mSmsManager.getPremiumSmsPermission(packageName);
- }
- } catch (RemoteException ex) {
- // ignored
- }
- return SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN;
- }
-
- @Override
- protected AlertDialog createDialog(int id, int errorCode) {
- // No dialogs for Permissions screen.
- return null;
- }
-
- public static CharSequence getSummary(AppEntry appEntry, Context context) {
- if (appEntry.info.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
- AppPermissions appPerms = new AppPermissions(context, appEntry.info.packageName);
- int count = appPerms.getPermissionCount();
- int grantedCount = appPerms.getGrantedPermissionsCount();
- return context.getResources().getQuantityString(R.plurals.runtime_permissions_summary,
- count, grantedCount, count);
- }
- AppSecurityPermissions asp = new AppSecurityPermissions(context,
- appEntry.info.packageName);
- int count = asp.getPermissionCount();
- return context.getResources().getQuantityString(R.plurals.permissions_summary,
- count, count);
- }
-
- @Override
- protected int getMetricsCategory() {
- return MetricsLogger.APPLICATIONS_APP_PERMISSION;
- }
-
- private static class PremiumSmsSelectionListener implements AdapterView.OnItemSelectedListener {
- private final String mPackageName;
- private final ISms mSmsManager;
-
- PremiumSmsSelectionListener(String packageName, ISms smsManager) {
- mPackageName = packageName;
- mSmsManager = smsManager;
- }
-
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position,
- long id) {
- if (position >= 0 && position < 3) {
- if (localLOGV) Log.d(TAG, "Selected premium SMS policy " + position);
- setPremiumSmsPermission(mPackageName, (position + 1));
- } else {
- Log.e(TAG, "Error: unknown premium SMS policy " + position);
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
- // Ignored
- }
-
- private void setPremiumSmsPermission(String packageName, int permission) {
- try {
- if (mSmsManager != null) {
- mSmsManager.setPremiumSmsPermission(packageName, permission);
- }
- } catch (RemoteException ex) {
- // ignored
- }
- }
- }
-
-}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/AppStateBaseBridge.java b/src/com/android/settings/applications/AppStateBaseBridge.java
index 04eb77bcf02..1e04e13cc21 100644
--- a/src/com/android/settings/applications/AppStateBaseBridge.java
+++ b/src/com/android/settings/applications/AppStateBaseBridge.java
@@ -19,8 +19,9 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import com.android.settings.applications.ApplicationsState.AppEntry;
-import com.android.settings.applications.ApplicationsState.Session;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.Session;
import java.util.ArrayList;
diff --git a/src/com/android/settings/applications/AppStateNotificationBridge.java b/src/com/android/settings/applications/AppStateNotificationBridge.java
index 4ac86506794..5a8e811a9f2 100644
--- a/src/com/android/settings/applications/AppStateNotificationBridge.java
+++ b/src/com/android/settings/applications/AppStateNotificationBridge.java
@@ -17,10 +17,11 @@ package com.android.settings.applications;
import android.content.pm.PackageManager;
-import com.android.settings.applications.ApplicationsState.AppEntry;
-import com.android.settings.applications.ApplicationsState.AppFilter;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.notification.NotificationBackend.AppRow;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.AppFilter;
import java.util.ArrayList;
diff --git a/src/com/android/settings/applications/AppStatePowerBridge.java b/src/com/android/settings/applications/AppStatePowerBridge.java
index 40163cb2b2e..3b1707f8baf 100644
--- a/src/com/android/settings/applications/AppStatePowerBridge.java
+++ b/src/com/android/settings/applications/AppStatePowerBridge.java
@@ -15,9 +15,10 @@
*/
package com.android.settings.applications;
-import com.android.settings.applications.ApplicationsState.AppEntry;
-import com.android.settings.applications.ApplicationsState.AppFilter;
import com.android.settings.fuelgauge.PowerWhitelistBackend;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.AppFilter;
import java.util.ArrayList;
diff --git a/src/com/android/settings/applications/AppStateUsageBridge.java b/src/com/android/settings/applications/AppStateUsageBridge.java
index 22f19b23f17..c06492c0d09 100644
--- a/src/com/android/settings/applications/AppStateUsageBridge.java
+++ b/src/com/android/settings/applications/AppStateUsageBridge.java
@@ -30,8 +30,9 @@ import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
-import com.android.settings.applications.ApplicationsState.AppEntry;
-import com.android.settings.applications.ApplicationsState.AppFilter;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.AppFilter;
import java.util.List;
diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java
index fe68cbc4e90..808f738e425 100644
--- a/src/com/android/settings/applications/AppStorageSettings.java
+++ b/src/com/android/settings/applications/AppStorageSettings.java
@@ -36,15 +36,15 @@ import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
-import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
import com.android.settings.DropDownPreference;
import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settings.applications.ApplicationsState.AppEntry;
-import com.android.settings.applications.ApplicationsState.Callbacks;
import com.android.settings.deviceinfo.StorageWizardMoveConfirm;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.Callbacks;
import java.util.Collections;
import java.util.List;
diff --git a/src/com/android/settings/applications/AppViewHolder.java b/src/com/android/settings/applications/AppViewHolder.java
index 34c99524532..f58cf067123 100644
--- a/src/com/android/settings/applications/AppViewHolder.java
+++ b/src/com/android/settings/applications/AppViewHolder.java
@@ -16,8 +16,6 @@
package com.android.settings.applications;
-import com.android.settings.R;
-
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -25,6 +23,9 @@ import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.settings.R;
+import com.android.settingslib.applications.ApplicationsState;
+
// View Holder used when displaying views
public class AppViewHolder {
public ApplicationsState.AppEntry entry;
diff --git a/src/com/android/settings/applications/ApplicationsState.java b/src/com/android/settings/applications/ApplicationsState.java
deleted file mode 100644
index 055e415ed21..00000000000
--- a/src/com/android/settings/applications/ApplicationsState.java
+++ /dev/null
@@ -1,1341 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications;
-
-import android.app.ActivityManager;
-import android.app.AppGlobals;
-import android.app.Application;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.IPackageStatsObserver;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageStats;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.ResolveInfo;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.text.format.Formatter;
-import android.util.Log;
-import android.util.SparseArray;
-
-import java.io.File;
-import java.text.Collator;
-import java.text.Normalizer;
-import java.text.Normalizer.Form;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-import java.util.regex.Pattern;
-
-/**
- * Keeps track of information about all installed applications, lazy-loading
- * as needed.
- */
-public class ApplicationsState {
- static final String TAG = "ApplicationsState";
- static final boolean DEBUG = false;
- static final boolean DEBUG_LOCKING = false;
-
- public static interface Callbacks {
- public void onRunningStateChanged(boolean running);
- public void onPackageListChanged();
- public void onRebuildComplete(ArrayList apps);
- public void onPackageIconChanged();
- public void onPackageSizeChanged(String packageName);
- public void onAllSizesComputed();
- public void onLauncherInfoChanged();
- public void onLoadEntriesCompleted();
- }
-
- public static interface AppFilter {
- public void init();
- public boolean filterApp(AppEntry info);
- }
-
- static final int SIZE_UNKNOWN = -1;
- static final int SIZE_INVALID = -2;
-
- static final Pattern REMOVE_DIACRITICALS_PATTERN
- = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
-
- public static String normalize(String str) {
- String tmp = Normalizer.normalize(str, Form.NFD);
- return REMOVE_DIACRITICALS_PATTERN.matcher(tmp)
- .replaceAll("").toLowerCase();
- }
-
- public static class SizeInfo {
- long cacheSize;
- long codeSize;
- long dataSize;
- long externalCodeSize;
- long externalDataSize;
-
- // This is the part of externalDataSize that is in the cache
- // section of external storage. Note that we don't just combine
- // this with cacheSize because currently the platform can't
- // automatically trim this data when needed, so it is something
- // the user may need to manage. The externalDataSize also includes
- // this value, since what this is here is really the part of
- // externalDataSize that we can just consider to be "cache" files
- // for purposes of cleaning them up in the app details UI.
- long externalCacheSize;
- }
-
- public static class AppEntry extends SizeInfo {
- final File apkFile;
- final long id;
- String label;
- long size;
- long internalSize;
- long externalSize;
-
- boolean mounted;
-
- boolean hasLauncherEntry;
-
- String getNormalizedLabel() {
- if (normalizedLabel != null) {
- return normalizedLabel;
- }
- normalizedLabel = normalize(label);
- return normalizedLabel;
- }
-
- // Need to synchronize on 'this' for the following.
- public ApplicationInfo info;
- Drawable icon;
- String sizeStr;
- String internalSizeStr;
- String externalSizeStr;
- boolean sizeStale;
- long sizeLoadStart;
-
- String normalizedLabel;
-
- // A location where extra info can be placed to be used by custom filters.
- Object extraInfo;
-
- AppEntry(Context context, ApplicationInfo info, long id) {
- apkFile = new File(info.sourceDir);
- this.id = id;
- this.info = info;
- this.size = SIZE_UNKNOWN;
- this.sizeStale = true;
- ensureLabel(context);
- }
-
- void ensureLabel(Context context) {
- if (this.label == null || !this.mounted) {
- if (!this.apkFile.exists()) {
- this.mounted = false;
- this.label = info.packageName;
- } else {
- this.mounted = true;
- CharSequence label = info.loadLabel(context.getPackageManager());
- this.label = label != null ? label.toString() : info.packageName;
- }
- }
- }
-
- boolean ensureIconLocked(Context context, PackageManager pm) {
- if (this.icon == null) {
- if (this.apkFile.exists()) {
- this.icon = getBadgedIcon(pm);
- return true;
- } else {
- this.mounted = false;
- this.icon = context.getDrawable(
- com.android.internal.R.drawable.sym_app_on_sd_unavailable_icon);
- }
- } else if (!this.mounted) {
- // If the app wasn't mounted but is now mounted, reload
- // its icon.
- if (this.apkFile.exists()) {
- this.mounted = true;
- this.icon = getBadgedIcon(pm);
- return true;
- }
- }
- 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 ALPHA_COMPARATOR = new Comparator() {
- private final Collator sCollator = Collator.getInstance();
- @Override
- public int compare(AppEntry object1, AppEntry object2) {
- return sCollator.compare(object1.label, object2.label);
- }
- };
-
- public static final Comparator SIZE_COMPARATOR
- = new Comparator() {
- private final Collator sCollator = Collator.getInstance();
- @Override
- public int compare(AppEntry object1, AppEntry object2) {
- if (object1.size < object2.size) return 1;
- if (object1.size > object2.size) return -1;
- return sCollator.compare(object1.label, object2.label);
- }
- };
-
- public static final Comparator INTERNAL_SIZE_COMPARATOR
- = new Comparator() {
- private final Collator sCollator = Collator.getInstance();
- @Override
- public int compare(AppEntry object1, AppEntry object2) {
- if (object1.internalSize < object2.internalSize) return 1;
- if (object1.internalSize > object2.internalSize) return -1;
- return sCollator.compare(object1.label, object2.label);
- }
- };
-
- public static final Comparator EXTERNAL_SIZE_COMPARATOR
- = new Comparator() {
- private final Collator sCollator = Collator.getInstance();
- @Override
- public int compare(AppEntry object1, AppEntry object2) {
- if (object1.externalSize < object2.externalSize) return 1;
- if (object1.externalSize > object2.externalSize) return -1;
- return sCollator.compare(object1.label, object2.label);
- }
- };
-
- public static final AppFilter FILTER_PERSONAL = new AppFilter() {
- private int mCurrentUser;
-
- public void init() {
- mCurrentUser = ActivityManager.getCurrentUser();
- }
-
- @Override
- public boolean filterApp(AppEntry entry) {
- return UserHandle.getUserId(entry.info.uid) == mCurrentUser;
- }
- };
-
- public static final AppFilter FILTER_WORK = new AppFilter() {
- private int mCurrentUser;
-
- public void init() {
- mCurrentUser = ActivityManager.getCurrentUser();
- }
-
- @Override
- public boolean filterApp(AppEntry entry) {
- return UserHandle.getUserId(entry.info.uid) != mCurrentUser;
- }
- };
-
- public static final AppFilter FILTER_DOWNLOADED_AND_LAUNCHER = new AppFilter() {
- public void init() {
- }
-
- @Override
- public boolean filterApp(AppEntry entry) {
- if ((entry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
- return true;
- } else if ((entry.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
- return true;
- } else if (entry.hasLauncherEntry) {
- return true;
- }
- return false;
- }
- };
-
- public static final AppFilter FILTER_THIRD_PARTY = new AppFilter() {
- public void init() {
- }
-
- @Override
- public boolean filterApp(AppEntry entry) {
- if ((entry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
- return true;
- } else if ((entry.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
- return true;
- }
- return false;
- }
- };
-
- public static final AppFilter FILTER_DISABLED = new AppFilter() {
- public void init() {
- }
-
- @Override
- public boolean filterApp(AppEntry entry) {
- return !entry.info.enabled;
- }
- };
-
- public static final AppFilter FILTER_ALL_ENABLED = new AppFilter() {
- public void init() {
- }
-
- @Override
- public boolean filterApp(AppEntry entry) {
- return entry.info.enabled;
- }
- };
-
- public static final AppFilter FILTER_EVERYTHING = new AppFilter() {
- public void init() {
- }
-
- @Override
- public boolean filterApp(AppEntry entry) {
- return true;
- }
- };
-
- public static final AppFilter FILTER_WITH_DOMAIN_URLS = new AppFilter() {
- public void init() {
- }
-
- @Override
- public boolean filterApp(AppEntry entry) {
- return (entry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
- }
- };
-
- public static class VolumeFilter implements AppFilter {
- private final String mVolumeUuid;
-
- public VolumeFilter(String volumeUuid) {
- mVolumeUuid = volumeUuid;
- }
-
- @Override
- public void init() {
- }
-
- @Override
- public boolean filterApp(AppEntry info) {
- return Objects.equals(info.info.volumeUuid, mVolumeUuid);
- }
- }
-
- public static class CompoundFilter implements AppFilter {
- private final AppFilter mFirstFilter;
- private final AppFilter mSecondFilter;
-
- public CompoundFilter(AppFilter first, AppFilter second) {
- mFirstFilter = first;
- mSecondFilter = second;
- }
-
- @Override
- public void init() {
- mFirstFilter.init();
- mSecondFilter.init();
- }
-
- @Override
- public boolean filterApp(AppEntry info) {
- return mFirstFilter.filterApp(info) && mSecondFilter.filterApp(info);
- }
- }
-
- final Context mContext;
- final PackageManager mPm;
- final IPackageManager mIpm;
- final UserManager mUm;
- final int mOwnerRetrieveFlags;
- final int mRetrieveFlags;
- PackageIntentReceiver mPackageIntentReceiver;
-
- boolean mResumed;
- boolean mHaveDisabledApps;
-
- // Information about all applications. Synchronize on mEntriesMap
- // to protect access to these.
- final ArrayList mSessions = new ArrayList();
- final ArrayList mRebuildingSessions = new ArrayList();
- final InterestingConfigChanges mInterestingConfigChanges = new InterestingConfigChanges();
- // Map: userid => (Map: package name => AppEntry)
- final SparseArray> mEntriesMap =
- new SparseArray>();
- final ArrayList mAppEntries = new ArrayList();
- List mApplications = new ArrayList();
- long mCurId = 1;
- String mCurComputingSizePkg;
- int mCurComputingSizeUserId;
- boolean mSessionsChanged;
-
- // Temporary for dispatching session callbacks. Only touched by main thread.
- final ArrayList mActiveSessions = new ArrayList();
-
- /**
- * Receives notifications when applications are added/removed.
- */
- private class PackageIntentReceiver extends BroadcastReceiver {
- void registerReceiver() {
- IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- filter.addDataScheme("package");
- mContext.registerReceiver(this, filter);
- // Register for events related to sdcard installation.
- IntentFilter sdFilter = new IntentFilter();
- sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
- sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
- 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() {
- mContext.unregisterReceiver(this);
- }
- @Override
- public void onReceive(Context context, Intent intent) {
- String actionStr = intent.getAction();
- if (Intent.ACTION_PACKAGE_ADDED.equals(actionStr)) {
- Uri data = intent.getData();
- String pkgName = data.getEncodedSchemeSpecificPart();
- for (int i = 0; i < mEntriesMap.size(); i++) {
- addPackage(pkgName, mEntriesMap.keyAt(i));
- }
- } else if (Intent.ACTION_PACKAGE_REMOVED.equals(actionStr)) {
- Uri data = intent.getData();
- String pkgName = data.getEncodedSchemeSpecificPart();
- for (int i = 0; i < mEntriesMap.size(); i++) {
- removePackage(pkgName, mEntriesMap.keyAt(i));
- }
- } else if (Intent.ACTION_PACKAGE_CHANGED.equals(actionStr)) {
- Uri data = intent.getData();
- String pkgName = data.getEncodedSchemeSpecificPart();
- for (int i = 0; i < mEntriesMap.size(); i++) {
- invalidatePackage(pkgName, mEntriesMap.keyAt(i));
- }
- } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr) ||
- Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(actionStr)) {
- // When applications become available or unavailable (perhaps because
- // the SD card was inserted or ejected) we need to refresh the
- // AppInfo with new label, icon and size information as appropriate
- // given the newfound (un)availability of the application.
- // A simple way to do that is to treat the refresh as a package
- // removal followed by a package addition.
- String pkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
- if (pkgList == null || pkgList.length == 0) {
- // Ignore
- return;
- }
- boolean avail = Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr);
- if (avail) {
- for (String pkgName : pkgList) {
- 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));
- }
- }
- }
-
- void rebuildActiveSessions() {
- synchronized (mEntriesMap) {
- if (!mSessionsChanged) {
- return;
- }
- mActiveSessions.clear();
- for (int i=0; i());
- }
- mThread = new HandlerThread("ApplicationsState.Loader",
- Process.THREAD_PRIORITY_BACKGROUND);
- mThread.start();
- mBackgroundHandler = new BackgroundHandler(mThread.getLooper());
-
- // Only the owner can see all apps.
- mOwnerRetrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES |
- PackageManager.GET_DISABLED_COMPONENTS |
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
- mRetrieveFlags = PackageManager.GET_DISABLED_COMPONENTS |
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
-
- /**
- * This is a trick to prevent the foreground thread from being delayed.
- * The problem is that Dalvik monitors are initially spin locks, to keep
- * them lightweight. This leads to unfair contention -- Even though the
- * background thread only holds the lock for a short amount of time, if
- * it keeps running and locking again it can prevent the main thread from
- * acquiring its lock for a long time... sometimes even > 5 seconds
- * (leading to an ANR).
- *
- * Dalvik will promote a monitor to a "real" lock if it detects enough
- * contention on it. It doesn't figure this out fast enough for us
- * here, though, so this little trick will force it to turn into a real
- * lock immediately.
- */
- synchronized (mEntriesMap) {
- try {
- mEntriesMap.wait(1);
- } catch (InterruptedException e) {
- }
- }
- }
-
- Looper getBackgroundLooper() {
- return mThread.getLooper();
- }
-
- public class Session {
- final Callbacks mCallbacks;
- boolean mResumed;
-
- // Rebuilding of app list. Synchronized on mRebuildSync.
- final Object mRebuildSync = new Object();
- boolean mRebuildRequested;
- boolean mRebuildAsync;
- AppFilter mRebuildFilter;
- Comparator mRebuildComparator;
- ArrayList mRebuildResult;
- ArrayList mLastAppList;
-
- Session(Callbacks callbacks) {
- mCallbacks = callbacks;
- }
-
- public void resume() {
- if (DEBUG_LOCKING) Log.v(TAG, "resume about to acquire lock...");
- synchronized (mEntriesMap) {
- if (!mResumed) {
- mResumed = true;
- mSessionsChanged = true;
- doResumeIfNeededLocked();
- }
- }
- if (DEBUG_LOCKING) Log.v(TAG, "...resume releasing lock");
- }
-
- public void pause() {
- if (DEBUG_LOCKING) Log.v(TAG, "pause about to acquire lock...");
- synchronized (mEntriesMap) {
- if (mResumed) {
- mResumed = false;
- mSessionsChanged = true;
- mBackgroundHandler.removeMessages(BackgroundHandler.MSG_REBUILD_LIST, this);
- doPauseIfNeededLocked();
- }
- if (DEBUG_LOCKING) Log.v(TAG, "...pause releasing lock");
- }
- }
-
- ArrayList getAllApps() {
- synchronized (mEntriesMap) {
- return new ArrayList<>(mAppEntries);
- }
- }
-
- // Creates a new list of app entries with the given filter and comparator.
- ArrayList rebuild(AppFilter filter, Comparator comparator) {
- synchronized (mRebuildSync) {
- synchronized (mEntriesMap) {
- mRebuildingSessions.add(this);
- mRebuildRequested = true;
- mRebuildAsync = false;
- mRebuildFilter = filter;
- mRebuildComparator = comparator;
- mRebuildResult = null;
- if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_REBUILD_LIST)) {
- Message msg = mBackgroundHandler.obtainMessage(
- BackgroundHandler.MSG_REBUILD_LIST);
- mBackgroundHandler.sendMessage(msg);
- }
- }
-
- // We will wait for .25s for the list to be built.
- long waitend = SystemClock.uptimeMillis()+250;
-
- while (mRebuildResult == null) {
- long now = SystemClock.uptimeMillis();
- if (now >= waitend) {
- break;
- }
- try {
- mRebuildSync.wait(waitend - now);
- } catch (InterruptedException e) {
- }
- }
-
- mRebuildAsync = true;
-
- return mRebuildResult;
- }
- }
-
- void handleRebuildList() {
- AppFilter filter;
- Comparator comparator;
- synchronized (mRebuildSync) {
- if (!mRebuildRequested) {
- return;
- }
-
- filter = mRebuildFilter;
- comparator = mRebuildComparator;
- mRebuildRequested = false;
- mRebuildFilter = null;
- mRebuildComparator = null;
- }
-
- Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
-
- if (filter != null) {
- filter.init();
- }
-
- List apps;
- synchronized (mEntriesMap) {
- apps = new ArrayList<>(mAppEntries);
- }
-
- ArrayList filteredApps = new ArrayList();
- if (DEBUG) Log.i(TAG, "Rebuilding...");
- for (int i=0; i();
- for (UserHandle user : mUm.getUserProfiles()) {
- try {
- // If this user is new, it needs a map created.
- if (mEntriesMap.indexOfKey(user.getIdentifier()) < 0) {
- mEntriesMap.put(user.getIdentifier(), new HashMap());
- }
- ParceledListSlice list =
- mIpm.getInstalledApplications(
- user.isOwner() ? mOwnerRetrieveFlags : mRetrieveFlags,
- user.getIdentifier());
- mApplications.addAll(list.getList());
- } catch (RemoteException e) {
- }
- }
-
- if (mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
- // If an interesting part of the configuration has changed, we
- // should completely reload the app entries.
- clearEntries();
- } else {
- for (int i=0; i mApplications.size()) {
- // There are less apps now, some must have been uninstalled.
- clearEntries();
- }
- mCurComputingSizePkg = null;
- if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
- mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
- }
- }
-
- private void clearEntries() {
- for (int i = 0; i < mEntriesMap.size(); i++) {
- mEntriesMap.valueAt(i).clear();
- }
- mAppEntries.clear();
- }
-
- public boolean haveDisabledApps() {
- return mHaveDisabledApps;
- }
-
- void doPauseIfNeededLocked() {
- if (!mResumed) {
- return;
- }
- for (int i=0; i sumCacheSizes now has lock");
- for (int i=mAppEntries.size()-1; i>=0; i--) {
- sum += mAppEntries.get(i).cacheSize;
- }
- if (DEBUG_LOCKING) Log.v(TAG, "...sumCacheSizes releasing lock");
- }
- return sum;
- }
-
- int indexOfApplicationInfoLocked(String pkgName, int userId) {
- for (int i=mApplications.size()-1; i>=0; i--) {
- ApplicationInfo appInfo = mApplications.get(i);
- if (appInfo.packageName.equals(pkgName)
- && UserHandle.getUserId(appInfo.uid) == userId) {
- return i;
- }
- }
- return -1;
- }
-
- void addPackage(String pkgName, int userId) {
- try {
- synchronized (mEntriesMap) {
- if (DEBUG_LOCKING) Log.v(TAG, "addPackage acquired lock");
- if (DEBUG) Log.i(TAG, "Adding package " + pkgName);
- if (!mResumed) {
- // If we are not resumed, we will do a full query the
- // next time we resume, so there is no reason to do work
- // here.
- if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: not resumed");
- return;
- }
- if (indexOfApplicationInfoLocked(pkgName, userId) >= 0) {
- if (DEBUG) Log.i(TAG, "Package already exists!");
- if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: already exists");
- return;
- }
- ApplicationInfo info = mIpm.getApplicationInfo(pkgName,
- userId == UserHandle.USER_OWNER ? mOwnerRetrieveFlags : mRetrieveFlags,
- userId);
- if (info == null) {
- return;
- }
- if (!info.enabled) {
- if (info.enabledSetting
- != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
- return;
- }
- mHaveDisabledApps = true;
- }
- mApplications.add(info);
- if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
- mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
- }
- if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_LIST_CHANGED)) {
- mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_LIST_CHANGED);
- }
- if (DEBUG_LOCKING) Log.v(TAG, "addPackage releasing lock");
- }
- } catch (RemoteException e) {
- }
- }
-
- void removePackage(String pkgName, int userId) {
- synchronized (mEntriesMap) {
- if (DEBUG_LOCKING) Log.v(TAG, "removePackage acquired lock");
- int idx = indexOfApplicationInfoLocked(pkgName, userId);
- if (DEBUG) Log.i(TAG, "removePackage: " + pkgName + " @ " + idx);
- if (idx >= 0) {
- AppEntry entry = mEntriesMap.get(userId).get(pkgName);
- if (DEBUG) Log.i(TAG, "removePackage: " + entry);
- if (entry != null) {
- mEntriesMap.get(userId).remove(pkgName);
- mAppEntries.remove(entry);
- }
- ApplicationInfo info = mApplications.get(idx);
- mApplications.remove(idx);
- if (!info.enabled) {
- mHaveDisabledApps = false;
- for (int i=0; i());
- 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 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) {
- 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 (entry == null) {
- if (DEBUG) Log.i(TAG, "Creating AppEntry for " + info.packageName);
- entry = new AppEntry(mContext, info, mCurId++);
- mEntriesMap.get(userId).put(info.packageName, entry);
- mAppEntries.add(entry);
- } else if (entry.info != info) {
- entry.info = info;
- }
- return entry;
- }
-
- // --------------------------------------------------------------
-
- private long getTotalInternalSize(PackageStats ps) {
- if (ps != null) {
- return ps.codeSize + ps.dataSize;
- }
- return SIZE_INVALID;
- }
-
- private long getTotalExternalSize(PackageStats ps) {
- if (ps != null) {
- // We also include the cache size here because for non-emulated
- // we don't automtically clean cache files.
- return ps.externalCodeSize + ps.externalDataSize
- + ps.externalCacheSize
- + ps.externalMediaSize + ps.externalObbSize;
- }
- return SIZE_INVALID;
- }
-
- private String getSizeStr(long size) {
- if (size >= 0) {
- return Formatter.formatFileSize(mContext, size);
- }
- return null;
- }
-
- final HandlerThread mThread;
- final BackgroundHandler mBackgroundHandler;
- class BackgroundHandler extends Handler {
- static final int MSG_REBUILD_LIST = 1;
- static final int MSG_LOAD_ENTRIES = 2;
- static final int MSG_LOAD_ICONS = 3;
- static final int MSG_LOAD_SIZES = 4;
- static final int MSG_LOAD_LAUNCHER = 5;
-
- boolean mRunning;
-
- final IPackageStatsObserver.Stub mStatsObserver = new IPackageStatsObserver.Stub() {
- public void onGetStatsCompleted(PackageStats stats, boolean succeeded) {
- boolean sizeChanged = false;
- synchronized (mEntriesMap) {
- if (DEBUG_LOCKING) Log.v(TAG, "onGetStatsCompleted acquired lock");
- HashMap userMap = mEntriesMap.get(stats.userHandle);
- if (userMap == null) {
- // The user must have been removed.
- return;
- }
- AppEntry entry = userMap.get(stats.packageName);
- if (entry != null) {
- synchronized (entry) {
- entry.sizeStale = false;
- entry.sizeLoadStart = 0;
- long externalCodeSize = stats.externalCodeSize
- + stats.externalObbSize;
- long externalDataSize = stats.externalDataSize
- + stats.externalMediaSize;
- long newSize = externalCodeSize + externalDataSize
- + getTotalInternalSize(stats);
- if (entry.size != newSize ||
- entry.cacheSize != stats.cacheSize ||
- entry.codeSize != stats.codeSize ||
- entry.dataSize != stats.dataSize ||
- entry.externalCodeSize != externalCodeSize ||
- entry.externalDataSize != externalDataSize ||
- entry.externalCacheSize != stats.externalCacheSize) {
- entry.size = newSize;
- entry.cacheSize = stats.cacheSize;
- entry.codeSize = stats.codeSize;
- entry.dataSize = stats.dataSize;
- entry.externalCodeSize = externalCodeSize;
- entry.externalDataSize = externalDataSize;
- entry.externalCacheSize = stats.externalCacheSize;
- entry.sizeStr = getSizeStr(entry.size);
- entry.internalSize = getTotalInternalSize(stats);
- entry.internalSizeStr = getSizeStr(entry.internalSize);
- entry.externalSize = getTotalExternalSize(stats);
- entry.externalSizeStr = getSizeStr(entry.externalSize);
- if (DEBUG) Log.i(TAG, "Set size of " + entry.label + " " + entry
- + ": " + entry.sizeStr);
- sizeChanged = true;
- }
- }
- if (sizeChanged) {
- Message msg = mMainHandler.obtainMessage(
- MainHandler.MSG_PACKAGE_SIZE_CHANGED, stats.packageName);
- mMainHandler.sendMessage(msg);
- }
- }
- if (mCurComputingSizePkg != null
- && (mCurComputingSizePkg.equals(stats.packageName)
- && mCurComputingSizeUserId == stats.userHandle)) {
- mCurComputingSizePkg = null;
- sendEmptyMessage(MSG_LOAD_SIZES);
- }
- if (DEBUG_LOCKING) Log.v(TAG, "onGetStatsCompleted releasing lock");
- }
- }
- };
-
- BackgroundHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- // Always try rebuilding list first thing, if needed.
- ArrayList rebuildingSessions = null;
- synchronized (mEntriesMap) {
- if (mRebuildingSessions.size() > 0) {
- rebuildingSessions = new ArrayList(mRebuildingSessions);
- mRebuildingSessions.clear();
- }
- }
- if (rebuildingSessions != null) {
- for (int i=0; i= 6) {
- sendEmptyMessage(MSG_LOAD_ENTRIES);
- } else {
- if (!mMainHandler.hasMessages(MainHandler.MSG_LOAD_ENTRIES_COMPLETE)) {
- mMainHandler.sendEmptyMessage(MainHandler.MSG_LOAD_ENTRIES_COMPLETE);
- }
- sendEmptyMessage(MSG_LOAD_LAUNCHER);
- }
- } break;
- case MSG_LOAD_LAUNCHER: {
- Intent launchIntent = new Intent(Intent.ACTION_MAIN, null)
- .addCategory(Intent.CATEGORY_LAUNCHER);
-
- for (int i = 0; i < mEntriesMap.size(); i++) {
- int userId = mEntriesMap.keyAt(i);
- List intents = mPm.queryIntentActivitiesAsUser(launchIntent,
- PackageManager.GET_DISABLED_COMPONENTS, userId);
- synchronized (mEntriesMap) {
- if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_LAUNCHER acquired lock");
- HashMap userEntries = mEntriesMap.valueAt(i);
- final int N = intents.size();
- for (int j = 0; j < N; j++) {
- String packageName = intents.get(j).activityInfo.packageName;
- AppEntry entry = userEntries.get(packageName);
- if (entry != null) {
- entry.hasLauncherEntry = true;
- } else {
- Log.w(TAG, "Cannot find pkg: " + packageName
- + " on user " + userId);
- }
- }
- if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_LAUNCHER releasing lock");
- }
- }
-
- if (!mMainHandler.hasMessages(MainHandler.MSG_LAUNCHER_INFO_CHANGED)) {
- mMainHandler.sendEmptyMessage(MainHandler.MSG_LAUNCHER_INFO_CHANGED);
- }
- sendEmptyMessage(MSG_LOAD_ICONS);
- } break;
- case MSG_LOAD_ICONS: {
- int numDone = 0;
- synchronized (mEntriesMap) {
- if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ICONS acquired lock");
- for (int i=0; i 0) {
- if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_ICON_CHANGED)) {
- mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_ICON_CHANGED);
- }
- }
- if (numDone >= 2) {
- sendEmptyMessage(MSG_LOAD_ICONS);
- } else {
- sendEmptyMessage(MSG_LOAD_SIZES);
- }
- } break;
- case MSG_LOAD_SIZES: {
- synchronized (mEntriesMap) {
- if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES acquired lock");
- if (mCurComputingSizePkg != null) {
- if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing: currently computing");
- return;
- }
-
- long now = SystemClock.uptimeMillis();
- for (int i=0; i