1e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornpackage com.android.settings.applications;
2e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
3e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.app.Application;
4e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.content.BroadcastReceiver;
5e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.content.Context;
6e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.content.Intent;
7e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.content.IntentFilter;
8e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.content.pm.ApplicationInfo;
9e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.content.pm.IPackageStatsObserver;
10e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.content.pm.PackageManager;
11e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.content.pm.PackageStats;
12e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException;
13e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.graphics.drawable.Drawable;
14e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.net.Uri;
15e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.os.Handler;
16e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.os.HandlerThread;
17e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.os.Looper;
18e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.os.Message;
19e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.os.Process;
20e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.os.SystemClock;
21c715fb1207361bb2a793752eefb02f1956075739Dianne Hackbornimport android.os.UserHandle;
22e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.text.format.Formatter;
23e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport android.util.Log;
24e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
25d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackbornimport java.io.File;
26e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport java.text.Collator;
27e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport java.text.Normalizer;
28e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport java.text.Normalizer.Form;
29e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport java.util.ArrayList;
30e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport java.util.Collections;
31e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport java.util.Comparator;
32e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport java.util.HashMap;
33e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport java.util.List;
34e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornimport java.util.regex.Pattern;
35e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
36e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn/**
37e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn * Keeps track of information about all installed applications, lazy-loading
38e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn * as needed.
39e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn */
40e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackbornpublic class ApplicationsState {
41e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    static final String TAG = "ApplicationsState";
42e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    static final boolean DEBUG = false;
434e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn    static final boolean DEBUG_LOCKING = false;
44e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
45e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    public static interface Callbacks {
46e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public void onRunningStateChanged(boolean running);
47e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public void onPackageListChanged();
4819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        public void onRebuildComplete(ArrayList<AppEntry> apps);
49e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public void onPackageIconChanged();
50e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public void onPackageSizeChanged(String packageName);
51e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public void onAllSizesComputed();
52e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
53e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
54e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    public static interface AppFilter {
556dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn        public void init();
56e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public boolean filterApp(ApplicationInfo info);
57e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
58e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
59e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    static final int SIZE_UNKNOWN = -1;
60e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    static final int SIZE_INVALID = -2;
61e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
62e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    static final Pattern REMOVE_DIACRITICALS_PATTERN
63e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
64e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
65e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    public static String normalize(String str) {
66e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        String tmp = Normalizer.normalize(str, Form.NFD);
67e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        return REMOVE_DIACRITICALS_PATTERN.matcher(tmp)
68e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                .replaceAll("").toLowerCase();
69e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
70e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
714e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn    public static class SizeInfo {
724e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn        long cacheSize;
734e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn        long codeSize;
744e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn        long dataSize;
75bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn        long externalCodeSize;
76bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn        long externalDataSize;
77313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn
78313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn        // This is the part of externalDataSize that is in the cache
79313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn        // section of external storage.  Note that we don't just combine
80313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn        // this with cacheSize because currently the platform can't
81313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn        // automatically trim this data when needed, so it is something
82313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn        // the user may need to manage.  The externalDataSize also includes
83313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn        // this value, since what this is here is really the part of
84313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn        // externalDataSize that we can just consider to be "cache" files
85313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn        // for purposes of cleaning them up in the app details UI.
86313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn        long externalCacheSize;
874e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn    }
884e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn
894e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn    public static class AppEntry extends SizeInfo {
90d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        final File apkFile;
91e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        final long id;
92d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        String label;
93e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        long size;
94430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        long internalSize;
95430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        long externalSize;
96e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
97d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        boolean mounted;
98d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn
99e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        String getNormalizedLabel() {
100e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            if (normalizedLabel != null) {
101e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                return normalizedLabel;
102e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
103e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            normalizedLabel = normalize(label);
104e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            return normalizedLabel;
105e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
106e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
107e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        // Need to synchronize on 'this' for the following.
108e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        ApplicationInfo info;
109e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        Drawable icon;
110e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        String sizeStr;
111bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn        String internalSizeStr;
112bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn        String externalSizeStr;
113e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        boolean sizeStale;
114e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        long sizeLoadStart;
115e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
116e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        String normalizedLabel;
117e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
118e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        AppEntry(Context context, ApplicationInfo info, long id) {
119d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            apkFile = new File(info.sourceDir);
120e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            this.id = id;
121e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            this.info = info;
122e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            this.size = SIZE_UNKNOWN;
123e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            this.sizeStale = true;
124d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            ensureLabel(context);
125d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        }
126d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn
127d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        void ensureLabel(Context context) {
128d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            if (this.label == null || !this.mounted) {
129d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                if (!this.apkFile.exists()) {
130d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    this.mounted = false;
131d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    this.label = info.packageName;
132d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                } else {
133d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    this.mounted = true;
134d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    CharSequence label = info.loadLabel(context.getPackageManager());
135d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    this.label = label != null ? label.toString() : info.packageName;
136d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                }
137d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            }
138d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        }
139d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn
140d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        boolean ensureIconLocked(Context context, PackageManager pm) {
141d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            if (this.icon == null) {
142d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                if (this.apkFile.exists()) {
143d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    this.icon = this.info.loadIcon(pm);
144d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    return true;
145d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                } else {
146d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    this.mounted = false;
147d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    this.icon = context.getResources().getDrawable(
148d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                            com.android.internal.R.drawable.sym_app_on_sd_unavailable_icon);
149d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                }
150d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            } else if (!this.mounted) {
151d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                // If the app wasn't mounted but is now mounted, reload
152d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                // its icon.
153d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                if (this.apkFile.exists()) {
154d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    this.mounted = true;
155d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    this.icon = this.info.loadIcon(pm);
156d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                    return true;
157d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                }
158d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            }
159d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            return false;
160e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
161e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
162e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
163e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    public static final Comparator<AppEntry> ALPHA_COMPARATOR = new Comparator<AppEntry>() {
164e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        private final Collator sCollator = Collator.getInstance();
165e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        @Override
166e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public int compare(AppEntry object1, AppEntry object2) {
1673db54cb97630fe83342c2ca189d13ff5a1a598d3Dianne Hackborn            final boolean normal1 = object1.info.enabled
1683db54cb97630fe83342c2ca189d13ff5a1a598d3Dianne Hackborn                    && (object1.info.flags&ApplicationInfo.FLAG_INSTALLED) != 0;
1693db54cb97630fe83342c2ca189d13ff5a1a598d3Dianne Hackborn            final boolean normal2 = object2.info.enabled
1703db54cb97630fe83342c2ca189d13ff5a1a598d3Dianne Hackborn                    && (object2.info.flags&ApplicationInfo.FLAG_INSTALLED) != 0;
1713db54cb97630fe83342c2ca189d13ff5a1a598d3Dianne Hackborn            if (normal1 != normal2) {
1723db54cb97630fe83342c2ca189d13ff5a1a598d3Dianne Hackborn                return normal1 ? -1 : 1;
173c883ee5eaae1666f8321cfcc3058fb3843e695dcDianne Hackborn            }
174e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            return sCollator.compare(object1.label, object2.label);
175e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
176e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    };
177e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
178430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn    public static final Comparator<AppEntry> SIZE_COMPARATOR
179430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            = new Comparator<AppEntry>() {
180e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        private final Collator sCollator = Collator.getInstance();
181e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        @Override
182e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public int compare(AppEntry object1, AppEntry object2) {
183e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            if (object1.size < object2.size) return 1;
184e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            if (object1.size > object2.size) return -1;
185e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            return sCollator.compare(object1.label, object2.label);
186e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
187e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    };
188e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
189430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn    public static final Comparator<AppEntry> INTERNAL_SIZE_COMPARATOR
190430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            = new Comparator<AppEntry>() {
191430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        private final Collator sCollator = Collator.getInstance();
192430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        @Override
193430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        public int compare(AppEntry object1, AppEntry object2) {
194430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            if (object1.internalSize < object2.internalSize) return 1;
195430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            if (object1.internalSize > object2.internalSize) return -1;
196430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            return sCollator.compare(object1.label, object2.label);
197430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        }
198430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn    };
199430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn
200430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn    public static final Comparator<AppEntry> EXTERNAL_SIZE_COMPARATOR
201430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            = new Comparator<AppEntry>() {
202430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        private final Collator sCollator = Collator.getInstance();
203430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        @Override
204430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        public int compare(AppEntry object1, AppEntry object2) {
205430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            if (object1.externalSize < object2.externalSize) return 1;
206430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            if (object1.externalSize > object2.externalSize) return -1;
207430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            return sCollator.compare(object1.label, object2.label);
208430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        }
209430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn    };
210430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn
211e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    public static final AppFilter THIRD_PARTY_FILTER = new AppFilter() {
2126dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn        public void init() {
2136dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn        }
2146dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn
215e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        @Override
216e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public boolean filterApp(ApplicationInfo info) {
2170f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn            if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
2180f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                return true;
2190f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn            } else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
220e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                return true;
221e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
222e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            return false;
223e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
224e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    };
225e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
226e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    public static final AppFilter ON_SD_CARD_FILTER = new AppFilter() {
2276dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn        final CanBeOnSdCardChecker mCanBeOnSdCardChecker
2286dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn                = new CanBeOnSdCardChecker();
2296dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn
2306dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn        public void init() {
2316dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn            mCanBeOnSdCardChecker.init();
2326dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn        }
2336dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn
234e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        @Override
235e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public boolean filterApp(ApplicationInfo info) {
2366dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn            return mCanBeOnSdCardChecker.check(info);
237e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
238e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    };
239e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
24018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn    public static final AppFilter DISABLED_FILTER = new AppFilter() {
24118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        public void init() {
24218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        }
24318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn
24418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        @Override
24518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        public boolean filterApp(ApplicationInfo info) {
24618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn            if (!info.enabled) {
24718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                return true;
24818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn            }
24918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn            return false;
25018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        }
25118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn    };
25218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn
25318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn    public static final AppFilter ALL_ENABLED_FILTER = new AppFilter() {
25418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        public void init() {
25518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        }
25618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn
25718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        @Override
25818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        public boolean filterApp(ApplicationInfo info) {
25918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn            if (info.enabled) {
26018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                return true;
26118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn            }
26218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn            return false;
26318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        }
26418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn    };
26518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn
266e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    final Context mContext;
267e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    final PackageManager mPm;
268c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn    final int mRetrieveFlags;
269e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    PackageIntentReceiver mPackageIntentReceiver;
270e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
271e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    boolean mResumed;
27218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn    boolean mHaveDisabledApps;
273e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
274309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    // Information about all applications.  Synchronize on mEntriesMap
275e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    // to protect access to these.
276309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    final ArrayList<Session> mSessions = new ArrayList<Session>();
277309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    final ArrayList<Session> mRebuildingSessions = new ArrayList<Session>();
2782372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn    final InterestingConfigChanges mInterestingConfigChanges = new InterestingConfigChanges();
279e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    final HashMap<String, AppEntry> mEntriesMap = new HashMap<String, AppEntry>();
280e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    final ArrayList<AppEntry> mAppEntries = new ArrayList<AppEntry>();
281e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>();
282e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    long mCurId = 1;
283e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    String mCurComputingSizePkg;
284309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    boolean mSessionsChanged;
285e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
286309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    // Temporary for dispatching session callbacks.  Only touched by main thread.
287309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    final ArrayList<Session> mActiveSessions = new ArrayList<Session>();
28819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
289e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    /**
290e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn     * Receives notifications when applications are added/removed.
291e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn     */
292e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    private class PackageIntentReceiver extends BroadcastReceiver {
293e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn         void registerReceiver() {
294e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
295e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
296e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
297e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             filter.addDataScheme("package");
298e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             mContext.registerReceiver(this, filter);
299e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             // Register for events related to sdcard installation.
300e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             IntentFilter sdFilter = new IntentFilter();
301e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
302e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
303e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             mContext.registerReceiver(this, sdFilter);
304e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn         }
305309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn         void unregisterReceiver() {
306309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn             mContext.unregisterReceiver(this);
307309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn         }
308e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn         @Override
309e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn         public void onReceive(Context context, Intent intent) {
310e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             String actionStr = intent.getAction();
311e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             if (Intent.ACTION_PACKAGE_ADDED.equals(actionStr)) {
312e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 Uri data = intent.getData();
313e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 String pkgName = data.getEncodedSchemeSpecificPart();
314e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 addPackage(pkgName);
315e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             } else if (Intent.ACTION_PACKAGE_REMOVED.equals(actionStr)) {
316e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 Uri data = intent.getData();
317e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 String pkgName = data.getEncodedSchemeSpecificPart();
318e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 removePackage(pkgName);
319e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             } else if (Intent.ACTION_PACKAGE_CHANGED.equals(actionStr)) {
320e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 Uri data = intent.getData();
321e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 String pkgName = data.getEncodedSchemeSpecificPart();
322c442e52dca4d32e2ea391e361c847ce834bf0dfdDianne Hackborn                 invalidatePackage(pkgName);
323e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr) ||
324e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                     Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(actionStr)) {
325e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 // When applications become available or unavailable (perhaps because
326e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 // the SD card was inserted or ejected) we need to refresh the
327e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 // AppInfo with new label, icon and size information as appropriate
328e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 // given the newfound (un)availability of the application.
329e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 // A simple way to do that is to treat the refresh as a package
330e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 // removal followed by a package addition.
331e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 String pkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
332e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 if (pkgList == null || pkgList.length == 0) {
333e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                     // Ignore
334e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                     return;
335e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 }
3360f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                 boolean avail = Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr);
337d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                 if (avail) {
338d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                     for (String pkgName : pkgList) {
339c442e52dca4d32e2ea391e361c847ce834bf0dfdDianne Hackborn                         invalidatePackage(pkgName);
340d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                     }
341e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                 }
342e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn             }
343e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn         }
344e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
345e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
346309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    void rebuildActiveSessions() {
347309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        synchronized (mEntriesMap) {
348309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            if (!mSessionsChanged) {
349309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                return;
350309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
351309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mActiveSessions.clear();
352309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            for (int i=0; i<mSessions.size(); i++) {
353309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                Session s = mSessions.get(i);
354309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                if (s.mResumed) {
355309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mActiveSessions.add(s);
356309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                }
357309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
358309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
359309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    }
360309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
361e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    class MainHandler extends Handler {
36219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        static final int MSG_REBUILD_COMPLETE = 1;
36319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        static final int MSG_PACKAGE_LIST_CHANGED = 2;
36419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        static final int MSG_PACKAGE_ICON_CHANGED = 3;
365e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        static final int MSG_PACKAGE_SIZE_CHANGED = 4;
366e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        static final int MSG_ALL_SIZES_COMPUTED = 5;
367e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        static final int MSG_RUNNING_STATE_CHANGED = 6;
368e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
369e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        @Override
370e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public void handleMessage(Message msg) {
371309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            rebuildActiveSessions();
372e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            switch (msg.what) {
37319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                case MSG_REBUILD_COMPLETE: {
374309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    Session s = (Session)msg.obj;
375309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    if (mActiveSessions.contains(s)) {
376309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        s.mCallbacks.onRebuildComplete(s.mLastAppList);
37719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    }
37819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                } break;
379e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                case MSG_PACKAGE_LIST_CHANGED: {
380309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    for (int i=0; i<mActiveSessions.size(); i++) {
381309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        mActiveSessions.get(i).mCallbacks.onPackageListChanged();
382e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
383e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                } break;
384e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                case MSG_PACKAGE_ICON_CHANGED: {
385309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    for (int i=0; i<mActiveSessions.size(); i++) {
386309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        mActiveSessions.get(i).mCallbacks.onPackageIconChanged();
387e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
388e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                } break;
389e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                case MSG_PACKAGE_SIZE_CHANGED: {
390309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    for (int i=0; i<mActiveSessions.size(); i++) {
391309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        mActiveSessions.get(i).mCallbacks.onPackageSizeChanged(
392309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                                (String)msg.obj);
393e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
394e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                } break;
395e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                case MSG_ALL_SIZES_COMPUTED: {
396309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    for (int i=0; i<mActiveSessions.size(); i++) {
397309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        mActiveSessions.get(i).mCallbacks.onAllSizesComputed();
398e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
399e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                } break;
400e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                case MSG_RUNNING_STATE_CHANGED: {
401309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    for (int i=0; i<mActiveSessions.size(); i++) {
402309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        mActiveSessions.get(i).mCallbacks.onRunningStateChanged(
403309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                                msg.arg1 != 0);
404e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
405e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                } break;
406e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
407e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
408e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
409e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
410e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    final MainHandler mMainHandler = new MainHandler();
411e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
412e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    // --------------------------------------------------------------
413e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
414e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    static final Object sLock = new Object();
415e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    static ApplicationsState sInstance;
416e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
417e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    static ApplicationsState getInstance(Application app) {
418e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        synchronized (sLock) {
419e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            if (sInstance == null) {
420e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                sInstance = new ApplicationsState(app);
421e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
422e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            return sInstance;
423e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
424e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
425e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
426e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    private ApplicationsState(Application app) {
427e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        mContext = app;
428e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        mPm = mContext.getPackageManager();
429e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        mThread = new HandlerThread("ApplicationsState.Loader",
430e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                Process.THREAD_PRIORITY_BACKGROUND);
431e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        mThread.start();
432e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        mBackgroundHandler = new BackgroundHandler(mThread.getLooper());
433c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn
434c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn        // Only the owner can see all apps.
435c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn        if (UserHandle.myUserId() == 0) {
436c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn            mRetrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES |
43743052367c654202a1a2124d44c7b33e92331d1f4Dianne Hackborn                    PackageManager.GET_DISABLED_COMPONENTS |
43843052367c654202a1a2124d44c7b33e92331d1f4Dianne Hackborn                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
439c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn        } else {
44043052367c654202a1a2124d44c7b33e92331d1f4Dianne Hackborn            mRetrieveFlags = PackageManager.GET_DISABLED_COMPONENTS |
44143052367c654202a1a2124d44c7b33e92331d1f4Dianne Hackborn                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
442c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn        }
443c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn
4444e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn        /**
4454e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * This is a trick to prevent the foreground thread from being delayed.
4464e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * The problem is that Dalvik monitors are initially spin locks, to keep
4474e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * them lightweight.  This leads to unfair contention -- Even though the
4484e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * background thread only holds the lock for a short amount of time, if
4494e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * it keeps running and locking again it can prevent the main thread from
4504e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * acquiring its lock for a long time...  sometimes even > 5 seconds
4514e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * (leading to an ANR).
4524e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         *
4534e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * Dalvik will promote a monitor to a "real" lock if it detects enough
4544e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * contention on it.  It doesn't figure this out fast enough for us
4554e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * here, though, so this little trick will force it to turn into a real
4564e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         * lock immediately.
4574e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn         */
4584e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn        synchronized (mEntriesMap) {
4594e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            try {
4604e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                mEntriesMap.wait(1);
4614e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            } catch (InterruptedException e) {
4624e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            }
4634e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn        }
464e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
465e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
466309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    public class Session {
467309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        final Callbacks mCallbacks;
468309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        boolean mResumed;
4692372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn
470309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        // Rebuilding of app list.  Synchronized on mRebuildSync.
471309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        final Object mRebuildSync = new Object();
472309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        boolean mRebuildRequested;
473309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        boolean mRebuildAsync;
474309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        AppFilter mRebuildFilter;
475309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        Comparator<AppEntry> mRebuildComparator;
476309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        ArrayList<AppEntry> mRebuildResult;
477309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        ArrayList<AppEntry> mLastAppList;
478309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
479309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        Session(Callbacks callbacks) {
480309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mCallbacks = callbacks;
481309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
482309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
483309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        public void resume() {
484309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            if (DEBUG_LOCKING) Log.v(TAG, "resume about to acquire lock...");
485309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            synchronized (mEntriesMap) {
486309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                if (!mResumed) {
487309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mResumed = true;
488309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mSessionsChanged = true;
489309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    doResumeIfNeededLocked();
490d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                }
491d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            }
4924e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            if (DEBUG_LOCKING) Log.v(TAG, "...resume releasing lock");
493e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
494e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
495309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        public void pause() {
496309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            if (DEBUG_LOCKING) Log.v(TAG, "pause about to acquire lock...");
497309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            synchronized (mEntriesMap) {
498309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                if (mResumed) {
499309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mResumed = false;
500309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mSessionsChanged = true;
501309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mBackgroundHandler.removeMessages(BackgroundHandler.MSG_REBUILD_LIST, this);
502309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    doPauseIfNeededLocked();
503309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                }
504309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                if (DEBUG_LOCKING) Log.v(TAG, "...pause releasing lock");
505309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
506e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
507e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
508309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        // Creates a new list of app entries with the given filter and comparator.
509309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        ArrayList<AppEntry> rebuild(AppFilter filter, Comparator<AppEntry> comparator) {
510309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            synchronized (mRebuildSync) {
511309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                synchronized (mEntriesMap) {
512309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mRebuildingSessions.add(this);
513309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mRebuildRequested = true;
514309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mRebuildAsync = false;
515309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mRebuildFilter = filter;
516309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mRebuildComparator = comparator;
517309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mRebuildResult = null;
518309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_REBUILD_LIST)) {
519309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        Message msg = mBackgroundHandler.obtainMessage(
520309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                                BackgroundHandler.MSG_REBUILD_LIST);
521309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        mBackgroundHandler.sendMessage(msg);
522309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    }
52319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                }
524309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
525309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                // We will wait for .25s for the list to be built.
526309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                long waitend = SystemClock.uptimeMillis()+250;
527309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
528309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                while (mRebuildResult == null) {
529309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    long now = SystemClock.uptimeMillis();
530309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    if (now >= waitend) {
531309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        break;
532309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    }
533309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    try {
534309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        mRebuildSync.wait(waitend - now);
535309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    } catch (InterruptedException e) {
536309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    }
53719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                }
53819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
539309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                mRebuildAsync = true;
54019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
541309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                return mRebuildResult;
542309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
54319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        }
54419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
545309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        void handleRebuildList() {
546309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            AppFilter filter;
547309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            Comparator<AppEntry> comparator;
548309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            synchronized (mRebuildSync) {
549309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                if (!mRebuildRequested) {
550309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    return;
551309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                }
552309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
553309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                filter = mRebuildFilter;
554309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                comparator = mRebuildComparator;
555309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                mRebuildRequested = false;
556309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                mRebuildFilter = null;
557309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                mRebuildComparator = null;
55819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            }
55919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
560309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
561309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
562309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            if (filter != null) {
563309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                filter.init();
564309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
565309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
566309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            List<ApplicationInfo> apps;
567309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            synchronized (mEntriesMap) {
568309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                apps = new ArrayList<ApplicationInfo>(mApplications);
569309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
570309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
571309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            ArrayList<AppEntry> filteredApps = new ArrayList<AppEntry>();
572309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            if (DEBUG) Log.i(TAG, "Rebuilding...");
573309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            for (int i=0; i<apps.size(); i++) {
574309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                ApplicationInfo info = apps.get(i);
575309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                if (filter == null || filter.filterApp(info)) {
576309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    synchronized (mEntriesMap) {
577309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        if (DEBUG_LOCKING) Log.v(TAG, "rebuild acquired lock");
578309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        AppEntry entry = getEntryLocked(info);
579309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        entry.ensureLabel(mContext);
580309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        if (DEBUG) Log.i(TAG, "Using " + info.packageName + ": " + entry);
581309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        filteredApps.add(entry);
582309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        if (DEBUG_LOCKING) Log.v(TAG, "rebuild releasing lock");
583309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    }
584309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                }
585309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
586309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
587309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            Collections.sort(filteredApps, comparator);
588309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
589309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            synchronized (mRebuildSync) {
590309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                if (!mRebuildRequested) {
591309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mLastAppList = filteredApps;
592309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    if (!mRebuildAsync) {
593309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        mRebuildResult = filteredApps;
594309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        mRebuildSync.notifyAll();
595309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    } else {
596309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        if (!mMainHandler.hasMessages(MainHandler.MSG_REBUILD_COMPLETE, this)) {
597309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                            Message msg = mMainHandler.obtainMessage(
598309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                                    MainHandler.MSG_REBUILD_COMPLETE, this);
599309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                            mMainHandler.sendMessage(msg);
600309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                        }
601309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    }
602309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                }
603309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
60419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
605309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
606309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
60719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
608309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        public void release() {
609309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            pause();
610309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            synchronized (mEntriesMap) {
611309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                mSessions.remove(this);
612309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
6136dc1bf84cf72dd72a2517878f6b280e8afdcf4c2Dianne Hackborn        }
614309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    }
615309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
616309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    public Session newSession(Callbacks callbacks) {
617309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        Session s = new Session(callbacks);
618e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        synchronized (mEntriesMap) {
619309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mSessions.add(s);
62019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        }
621309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        return s;
622309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    }
62319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
624309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    void doResumeIfNeededLocked() {
625309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        if (mResumed) {
626309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            return;
627309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
628309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        mResumed = true;
629309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        if (mPackageIntentReceiver == null) {
630309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mPackageIntentReceiver = new PackageIntentReceiver();
631309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mPackageIntentReceiver.registerReceiver();
632309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
633c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn        mApplications = mPm.getInstalledApplications(mRetrieveFlags);
634309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        if (mApplications == null) {
635309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mApplications = new ArrayList<ApplicationInfo>();
636309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
637309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn
638309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        if (mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
639309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            // If an interesting part of the configuration has changed, we
640309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            // should completely reload the app entries.
641309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mEntriesMap.clear();
642309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mAppEntries.clear();
643309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        } else {
644309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            for (int i=0; i<mAppEntries.size(); i++) {
645309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                mAppEntries.get(i).sizeStale = true;
646e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
647e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
64819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
64918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        mHaveDisabledApps = false;
650309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        for (int i=0; i<mApplications.size(); i++) {
651309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            final ApplicationInfo info = mApplications.get(i);
652309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            // Need to trim out any applications that are disabled by
653309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            // something different than the user.
65418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn            if (!info.enabled) {
65518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                if (info.enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
65618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                    mApplications.remove(i);
65718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                    i--;
65818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                    continue;
65918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                }
66018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                mHaveDisabledApps = true;
661309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
662309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            final AppEntry entry = mEntriesMap.get(info.packageName);
663309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            if (entry != null) {
664309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                entry.info = info;
66519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            }
66619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        }
667309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        mCurComputingSizePkg = null;
668309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
669309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
670309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
671309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    }
67219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
67318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn    public boolean haveDisabledApps() {
67418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn        return mHaveDisabledApps;
67518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn    }
67618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn
677309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn    void doPauseIfNeededLocked() {
678309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        if (!mResumed) {
679309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            return;
680309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
681309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        for (int i=0; i<mSessions.size(); i++) {
682309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            if (mSessions.get(i).mResumed) {
683309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                return;
684309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
685309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
686309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        mResumed = false;
687309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        if (mPackageIntentReceiver != null) {
688309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mPackageIntentReceiver.unregisterReceiver();
689309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            mPackageIntentReceiver = null;
690309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn        }
691e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
692e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
6930f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn    AppEntry getEntry(String packageName) {
6944e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn        if (DEBUG_LOCKING) Log.v(TAG, "getEntry about to acquire lock...");
6950f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn        synchronized (mEntriesMap) {
6960f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn            AppEntry entry = mEntriesMap.get(packageName);
6970f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn            if (entry == null) {
6980f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                for (int i=0; i<mApplications.size(); i++) {
6990f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                    ApplicationInfo info = mApplications.get(i);
7000f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                    if (packageName.equals(info.packageName)) {
7010f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                        entry = getEntryLocked(info);
7020f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                        break;
7030f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                    }
7040f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                }
7050f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn            }
7064e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            if (DEBUG_LOCKING) Log.v(TAG, "...getEntry releasing lock");
7070f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn            return entry;
7080f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn        }
7090f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn    }
7100f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn
711e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    void ensureIcon(AppEntry entry) {
712e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        if (entry.icon != null) {
713e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            return;
714e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
715508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        synchronized (entry) {
716d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            entry.ensureIconLocked(mContext, mPm);
717e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
718e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
719d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn
720e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    void requestSize(String packageName) {
7214e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn        if (DEBUG_LOCKING) Log.v(TAG, "requestSize about to acquire lock...");
722e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        synchronized (mEntriesMap) {
723e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            AppEntry entry = mEntriesMap.get(packageName);
724e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            if (entry != null) {
725e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                mPm.getPackageSizeInfo(packageName, mBackgroundHandler.mStatsObserver);
726e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
7274e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            if (DEBUG_LOCKING) Log.v(TAG, "...requestSize releasing lock");
728e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
729e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
730e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
731d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn    long sumCacheSizes() {
732d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        long sum = 0;
7334e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn        if (DEBUG_LOCKING) Log.v(TAG, "sumCacheSizes about to acquire lock...");
734d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        synchronized (mEntriesMap) {
7354e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            if (DEBUG_LOCKING) Log.v(TAG, "-> sumCacheSizes now has lock");
736d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            for (int i=mAppEntries.size()-1; i>=0; i--) {
737d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                sum += mAppEntries.get(i).cacheSize;
738d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn            }
7394e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            if (DEBUG_LOCKING) Log.v(TAG, "...sumCacheSizes releasing lock");
740d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        }
741d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        return sum;
742d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn    }
743d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn
744e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    int indexOfApplicationInfoLocked(String pkgName) {
745e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        for (int i=mApplications.size()-1; i>=0; i--) {
746e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            if (mApplications.get(i).packageName.equals(pkgName)) {
747e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                return i;
748e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
749e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
750e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        return -1;
751e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
752e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
753e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    void addPackage(String pkgName) {
754e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        try {
755e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            synchronized (mEntriesMap) {
7564e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                if (DEBUG_LOCKING) Log.v(TAG, "addPackage acquired lock");
757e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                if (DEBUG) Log.i(TAG, "Adding package " + pkgName);
758e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                if (!mResumed) {
759e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    // If we are not resumed, we will do a full query the
760e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    // next time we resume, so there is no reason to do work
761e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    // here.
7624e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                    if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: not resumed");
763e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    return;
764e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                }
765e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                if (indexOfApplicationInfoLocked(pkgName) >= 0) {
766e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    if (DEBUG) Log.i(TAG, "Package already exists!");
7674e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                    if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: already exists");
768e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    return;
769e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                }
770c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn                ApplicationInfo info = mPm.getApplicationInfo(pkgName, mRetrieveFlags);
77118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                if (!info.enabled) {
77218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                    if (info.enabledSetting
77318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                            != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
77418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                        return;
77518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                    }
77618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                    mHaveDisabledApps = true;
77718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                }
778e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                mApplications.add(info);
779e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
780e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
781e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                }
782e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_LIST_CHANGED)) {
783e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_LIST_CHANGED);
784e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                }
7854e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                if (DEBUG_LOCKING) Log.v(TAG, "addPackage releasing lock");
786e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
787e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        } catch (NameNotFoundException e) {
788e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
789e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
790e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
791e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    void removePackage(String pkgName) {
792e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        synchronized (mEntriesMap) {
7934e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            if (DEBUG_LOCKING) Log.v(TAG, "removePackage acquired lock");
794e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            int idx = indexOfApplicationInfoLocked(pkgName);
795e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            if (DEBUG) Log.i(TAG, "removePackage: " + pkgName + " @ " + idx);
796e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            if (idx >= 0) {
797e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                AppEntry entry = mEntriesMap.get(pkgName);
798e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                if (DEBUG) Log.i(TAG, "removePackage: " + entry);
799e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                if (entry != null) {
800e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    mEntriesMap.remove(pkgName);
801e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    mAppEntries.remove(entry);
802e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                }
80318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                ApplicationInfo info = mApplications.get(idx);
804e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                mApplications.remove(idx);
80518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                if (!info.enabled) {
80618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                    mHaveDisabledApps = false;
80718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                    for (int i=0; i<mApplications.size(); i++) {
80818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                        if (!mApplications.get(i).enabled) {
80918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                            mHaveDisabledApps = true;
81018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                            break;
81118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                        }
81218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                    }
81318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn                }
814e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_LIST_CHANGED)) {
815e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_LIST_CHANGED);
816e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                }
817e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
8184e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn            if (DEBUG_LOCKING) Log.v(TAG, "removePackage releasing lock");
819e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
820e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
821e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
822c442e52dca4d32e2ea391e361c847ce834bf0dfdDianne Hackborn    void invalidatePackage(String pkgName) {
823c442e52dca4d32e2ea391e361c847ce834bf0dfdDianne Hackborn        removePackage(pkgName);
824c442e52dca4d32e2ea391e361c847ce834bf0dfdDianne Hackborn        addPackage(pkgName);
825c442e52dca4d32e2ea391e361c847ce834bf0dfdDianne Hackborn    }
826c442e52dca4d32e2ea391e361c847ce834bf0dfdDianne Hackborn
827e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    AppEntry getEntryLocked(ApplicationInfo info) {
828e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        AppEntry entry = mEntriesMap.get(info.packageName);
829e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        if (DEBUG) Log.i(TAG, "Looking up entry of pkg " + info.packageName + ": " + entry);
830e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        if (entry == null) {
831e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            if (DEBUG) Log.i(TAG, "Creating AppEntry for " + info.packageName);
832e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            entry = new AppEntry(mContext, info, mCurId++);
833e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            mEntriesMap.put(info.packageName, entry);
834e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            mAppEntries.add(entry);
835e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        } else if (entry.info != info) {
836e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            entry.info = info;
837e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
838e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        return entry;
839e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
840e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
841e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    // --------------------------------------------------------------
842e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
843424acfb7ad469efb0a51c69fc8713cc96e2357b0Kenny Root    private long getTotalInternalSize(PackageStats ps) {
844e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        if (ps != null) {
845424acfb7ad469efb0a51c69fc8713cc96e2357b0Kenny Root            return ps.codeSize + ps.dataSize;
846424acfb7ad469efb0a51c69fc8713cc96e2357b0Kenny Root        }
847424acfb7ad469efb0a51c69fc8713cc96e2357b0Kenny Root        return SIZE_INVALID;
848424acfb7ad469efb0a51c69fc8713cc96e2357b0Kenny Root    }
849424acfb7ad469efb0a51c69fc8713cc96e2357b0Kenny Root
850424acfb7ad469efb0a51c69fc8713cc96e2357b0Kenny Root    private long getTotalExternalSize(PackageStats ps) {
851424acfb7ad469efb0a51c69fc8713cc96e2357b0Kenny Root        if (ps != null) {
8521f6ddac9f41f341073e7cedd8f777a43b7d11679Dianne Hackborn            // We also include the cache size here because for non-emulated
8531f6ddac9f41f341073e7cedd8f777a43b7d11679Dianne Hackborn            // we don't automtically clean cache files.
854bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn            return ps.externalCodeSize + ps.externalDataSize
8551f6ddac9f41f341073e7cedd8f777a43b7d11679Dianne Hackborn                    + ps.externalCacheSize
856bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn                    + ps.externalMediaSize + ps.externalObbSize;
857e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
858e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        return SIZE_INVALID;
859e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
860e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
861e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    private String getSizeStr(long size) {
862e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        if (size >= 0) {
863e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            return Formatter.formatFileSize(mContext, size);
864e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
865e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        return null;
866e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
867e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
868e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    final HandlerThread mThread;
869e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    final BackgroundHandler mBackgroundHandler;
870e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    class BackgroundHandler extends Handler {
87119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        static final int MSG_REBUILD_LIST = 1;
87219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        static final int MSG_LOAD_ENTRIES = 2;
87319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        static final int MSG_LOAD_ICONS = 3;
87419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        static final int MSG_LOAD_SIZES = 4;
875e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
876e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        boolean mRunning;
877e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
878e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        final IPackageStatsObserver.Stub mStatsObserver = new IPackageStatsObserver.Stub() {
879e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            public void onGetStatsCompleted(PackageStats stats, boolean succeeded) {
880e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                boolean sizeChanged = false;
881e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                synchronized (mEntriesMap) {
8824e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                    if (DEBUG_LOCKING) Log.v(TAG, "onGetStatsCompleted acquired lock");
883e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    AppEntry entry = mEntriesMap.get(stats.packageName);
884e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    if (entry != null) {
885e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        synchronized (entry) {
886e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            entry.sizeStale = false;
887e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            entry.sizeLoadStart = 0;
888bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn                            long externalCodeSize = stats.externalCodeSize
889bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn                                    + stats.externalObbSize;
890bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn                            long externalDataSize = stats.externalDataSize
8911f6ddac9f41f341073e7cedd8f777a43b7d11679Dianne Hackborn                                    + stats.externalMediaSize;
892bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn                            long newSize = externalCodeSize + externalDataSize
893bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn                                    + getTotalInternalSize(stats);
8940f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                            if (entry.size != newSize ||
8950f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                                    entry.cacheSize != stats.cacheSize ||
8960f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                                    entry.codeSize != stats.codeSize ||
897424acfb7ad469efb0a51c69fc8713cc96e2357b0Kenny Root                                    entry.dataSize != stats.dataSize ||
898bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn                                    entry.externalCodeSize != externalCodeSize ||
899313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn                                    entry.externalDataSize != externalDataSize ||
900313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn                                    entry.externalCacheSize != stats.externalCacheSize) {
901e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                entry.size = newSize;
9020f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                                entry.cacheSize = stats.cacheSize;
9030f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                                entry.codeSize = stats.codeSize;
9040f9daab75f1557722b6e687a68eebfd5d28cbc51Dianne Hackborn                                entry.dataSize = stats.dataSize;
905bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn                                entry.externalCodeSize = externalCodeSize;
906bd9ddab4f4e1f47b141abdcc0248cc716112b3c7Dianne Hackborn                                entry.externalDataSize = externalDataSize;
907313ab1727014d535790bc89afdcf725ff936e5b4Dianne Hackborn                                entry.externalCacheSize = stats.externalCacheSize;
908e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                entry.sizeStr = getSizeStr(entry.size);
909430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn                                entry.internalSize = getTotalInternalSize(stats);
910430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn                                entry.internalSizeStr = getSizeStr(entry.internalSize);
911430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn                                entry.externalSize = getTotalExternalSize(stats);
912430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn                                entry.externalSizeStr = getSizeStr(entry.externalSize);
913e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                if (DEBUG) Log.i(TAG, "Set size of " + entry.label + " " + entry
914e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                        + ": " + entry.sizeStr);
915e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                sizeChanged = true;
916e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            }
917e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        }
918e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        if (sizeChanged) {
919e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            Message msg = mMainHandler.obtainMessage(
920e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                    MainHandler.MSG_PACKAGE_SIZE_CHANGED, stats.packageName);
921e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            mMainHandler.sendMessage(msg);
922e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        }
923e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
924e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    if (mCurComputingSizePkg == null
925e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            || mCurComputingSizePkg.equals(stats.packageName)) {
926e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        mCurComputingSizePkg = null;
927e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        sendEmptyMessage(MSG_LOAD_SIZES);
928e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
9294e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                    if (DEBUG_LOCKING) Log.v(TAG, "onGetStatsCompleted releasing lock");
930e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                }
931e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
932e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        };
933e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
934e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        BackgroundHandler(Looper looper) {
935e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            super(looper);
936e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
937e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
938e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        @Override
939e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        public void handleMessage(Message msg) {
94019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            // Always try rebuilding list first thing, if needed.
941309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            ArrayList<Session> rebuildingSessions = null;
942309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            synchronized (mEntriesMap) {
943309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                if (mRebuildingSessions.size() > 0) {
944309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    rebuildingSessions = new ArrayList<Session>(mRebuildingSessions);
945309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    mRebuildingSessions.clear();
946309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                }
947309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
948309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            if (rebuildingSessions != null) {
949309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                for (int i=0; i<rebuildingSessions.size(); i++) {
950309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                    rebuildingSessions.get(i).handleRebuildList();
951309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn                }
952309c5dcee18ced447d049d5de882a9586694e04cDianne Hackborn            }
95319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
954e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            switch (msg.what) {
95519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                case MSG_REBUILD_LIST: {
95619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                } break;
957e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                case MSG_LOAD_ENTRIES: {
958e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    int numDone = 0;
959e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    synchronized (mEntriesMap) {
9604e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ENTRIES acquired lock");
961e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        for (int i=0; i<mApplications.size() && numDone<6; i++) {
962e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            if (!mRunning) {
963e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                mRunning = true;
964e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                Message m = mMainHandler.obtainMessage(
965e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                        MainHandler.MSG_RUNNING_STATE_CHANGED, 1);
966e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                mMainHandler.sendMessage(m);
967e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            }
968e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            ApplicationInfo info = mApplications.get(i);
969e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            if (mEntriesMap.get(info.packageName) == null) {
970e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                numDone++;
971e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                getEntryLocked(info);
972e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            }
973e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        }
9744e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ENTRIES releasing lock");
975e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
976e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
977e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    if (numDone >= 6) {
978e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        sendEmptyMessage(MSG_LOAD_ENTRIES);
979e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    } else {
980e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        sendEmptyMessage(MSG_LOAD_ICONS);
981e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
982e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                } break;
983e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                case MSG_LOAD_ICONS: {
984e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    int numDone = 0;
985e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    synchronized (mEntriesMap) {
9864e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ICONS acquired lock");
987e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        for (int i=0; i<mAppEntries.size() && numDone<2; i++) {
988e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            AppEntry entry = mAppEntries.get(i);
989d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                            if (entry.icon == null || !entry.mounted) {
990e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                synchronized (entry) {
991d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                                    if (entry.ensureIconLocked(mContext, mPm)) {
992d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                                        if (!mRunning) {
993d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                                            mRunning = true;
994d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                                            Message m = mMainHandler.obtainMessage(
995d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                                                    MainHandler.MSG_RUNNING_STATE_CHANGED, 1);
996d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                                            mMainHandler.sendMessage(m);
997d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                                        }
998d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                                        numDone++;
999d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn                                    }
1000e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                }
1001e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            }
1002e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        }
10034e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ICONS releasing lock");
1004e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
1005e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    if (numDone > 0) {
1006e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_ICON_CHANGED)) {
1007e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_ICON_CHANGED);
1008e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        }
1009e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
1010e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    if (numDone >= 2) {
1011e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        sendEmptyMessage(MSG_LOAD_ICONS);
1012e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    } else {
1013e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        sendEmptyMessage(MSG_LOAD_SIZES);
1014e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
1015e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                } break;
1016e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                case MSG_LOAD_SIZES: {
1017e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    synchronized (mEntriesMap) {
10184e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES acquired lock");
1019e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        if (mCurComputingSizePkg != null) {
10204e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                            if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing: currently computing");
1021e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            return;
1022e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        }
1023e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
1024e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        long now = SystemClock.uptimeMillis();
1025e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        for (int i=0; i<mAppEntries.size(); i++) {
1026e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            AppEntry entry = mAppEntries.get(i);
1027e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            if (entry.size == SIZE_UNKNOWN || entry.sizeStale) {
1028e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                if (entry.sizeLoadStart == 0 ||
1029e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                        (entry.sizeLoadStart < (now-20*1000))) {
1030e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                    if (!mRunning) {
1031e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                        mRunning = true;
1032e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                        Message m = mMainHandler.obtainMessage(
1033e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                                MainHandler.MSG_RUNNING_STATE_CHANGED, 1);
1034e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                        mMainHandler.sendMessage(m);
1035e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                    }
1036e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                    entry.sizeLoadStart = now;
1037e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                    mCurComputingSizePkg = entry.info.packageName;
1038e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                    mPm.getPackageSizeInfo(mCurComputingSizePkg, mStatsObserver);
1039e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                }
10404e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                                if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing: now computing");
1041e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                return;
1042e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            }
1043e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        }
1044e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        if (!mMainHandler.hasMessages(MainHandler.MSG_ALL_SIZES_COMPUTED)) {
1045e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            mMainHandler.sendEmptyMessage(MainHandler.MSG_ALL_SIZES_COMPUTED);
1046e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            mRunning = false;
1047e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            Message m = mMainHandler.obtainMessage(
1048e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                                    MainHandler.MSG_RUNNING_STATE_CHANGED, 0);
1049e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                            mMainHandler.sendMessage(m);
1050e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                        }
10514e4ed14ee2b82cb90a25b3027eb36f190ce2e1e7Dianne Hackborn                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing lock");
1052e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                    }
1053e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn                } break;
1054e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn            }
1055e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn        }
1056e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn
1057e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn    }
1058e7623f775cb37a8de049dae8c03b5b396526fdd1Dianne Hackborn}
1059