195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler/*
295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * Copyright (C) 2015 The Android Open Source Project
395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler *
495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * Licensed under the Apache License, Version 2.0 (the "License");
595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * you may not use this file except in compliance with the License.
695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * You may obtain a copy of the License at
795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler *
895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler *      http://www.apache.org/licenses/LICENSE-2.0
995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler *
1095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * Unless required by applicable law or agreed to in writing, software
1195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * distributed under the License is distributed on an "AS IS" BASIS,
1295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * See the License for the specific language governing permissions and
1495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * limitations under the License.
1595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler */
1695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
1795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerpackage com.android.settingslib.applications;
1895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
1995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.app.ActivityManager;
2095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.app.AppGlobals;
2195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.app.Application;
2295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.BroadcastReceiver;
2395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.Context;
2495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.Intent;
2595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.IntentFilter;
2695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.pm.ApplicationInfo;
2795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.pm.IPackageManager;
2895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.pm.IPackageStatsObserver;
2995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.pm.PackageManager;
3095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.pm.PackageStats;
3195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.pm.ParceledListSlice;
3295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.content.pm.ResolveInfo;
332b45f8a6ce623012b2fc6237acd1bdc6ebe2c85cXiaohui Chenimport android.content.pm.UserInfo;
3495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.graphics.drawable.Drawable;
3595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.net.Uri;
3695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.os.Handler;
3795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.os.HandlerThread;
3895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.os.Looper;
3995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.os.Message;
4095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.os.Process;
4195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.os.RemoteException;
4295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.os.SystemClock;
4395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.os.UserHandle;
4495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.os.UserManager;
4595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.text.format.Formatter;
4695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.util.Log;
4795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport android.util.SparseArray;
4895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
49b87b0edfb36bccdbc5ca33d85e8917c6c7f23190Ricky Waiimport com.android.internal.util.ArrayUtils;
50b87b0edfb36bccdbc5ca33d85e8917c6c7f23190Ricky Wai
5195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.io.File;
5295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.text.Collator;
5395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.text.Normalizer;
5495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.text.Normalizer.Form;
5595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.util.ArrayList;
5695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.util.Collections;
5795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.util.Comparator;
5895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.util.HashMap;
5995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.util.List;
6095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.util.Objects;
6195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerimport java.util.regex.Pattern;
6295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
6395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler/**
6495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * Keeps track of information about all installed applications, lazy-loading
6595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler * as needed.
6695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler */
6795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantlerpublic class ApplicationsState {
6895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    static final String TAG = "ApplicationsState";
6995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    static final boolean DEBUG = false;
7095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    static final boolean DEBUG_LOCKING = false;
7195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
7295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final int SIZE_UNKNOWN = -1;
7395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final int SIZE_INVALID = -2;
7495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
7595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    static final Pattern REMOVE_DIACRITICALS_PATTERN
7695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
7795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
7895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    static final Object sLock = new Object();
7995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    static ApplicationsState sInstance;
8095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
8195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static ApplicationsState getInstance(Application app) {
8295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (sLock) {
8395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (sInstance == null) {
8495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                sInstance = new ApplicationsState(app);
8595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
8695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return sInstance;
8795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
8895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
8995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
9095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final Context mContext;
9195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final PackageManager mPm;
9295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final IPackageManager mIpm;
9395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final UserManager mUm;
942b45f8a6ce623012b2fc6237acd1bdc6ebe2c85cXiaohui Chen    final int mAdminRetrieveFlags;
9595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final int mRetrieveFlags;
9695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    PackageIntentReceiver mPackageIntentReceiver;
9795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
9895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    boolean mResumed;
9995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    boolean mHaveDisabledApps;
10095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
10195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    // Information about all applications.  Synchronize on mEntriesMap
10295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    // to protect access to these.
10395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final ArrayList<Session> mSessions = new ArrayList<Session>();
10495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final ArrayList<Session> mRebuildingSessions = new ArrayList<Session>();
10595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final InterestingConfigChanges mInterestingConfigChanges = new InterestingConfigChanges();
10695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    // Map: userid => (Map: package name => AppEntry)
10795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final SparseArray<HashMap<String, AppEntry>> mEntriesMap =
10895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            new SparseArray<HashMap<String, AppEntry>>();
10995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final ArrayList<AppEntry> mAppEntries = new ArrayList<AppEntry>();
11095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>();
11195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    long mCurId = 1;
11295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    String mCurComputingSizePkg;
11395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    int mCurComputingSizeUserId;
11495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    boolean mSessionsChanged;
11595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
11695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    // Temporary for dispatching session callbacks.  Only touched by main thread.
11795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final ArrayList<Session> mActiveSessions = new ArrayList<Session>();
11895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
11995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final HandlerThread mThread;
12095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    final BackgroundHandler mBackgroundHandler;
1212a5d79aa6fd882ef6f46439f5156c516f173f06aJason Monk    final MainHandler mMainHandler = new MainHandler(Looper.getMainLooper());
12295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
12395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private ApplicationsState(Application app) {
12495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mContext = app;
12595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mPm = mContext.getPackageManager();
12695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mIpm = AppGlobals.getPackageManager();
12795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mUm = (UserManager) app.getSystemService(Context.USER_SERVICE);
128b87b0edfb36bccdbc5ca33d85e8917c6c7f23190Ricky Wai        for (int userId : mUm.getProfileIdsWithDisabled(UserHandle.myUserId())) {
129b87b0edfb36bccdbc5ca33d85e8917c6c7f23190Ricky Wai            mEntriesMap.put(userId, new HashMap<String, AppEntry>());
13095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
13195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mThread = new HandlerThread("ApplicationsState.Loader",
13295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                Process.THREAD_PRIORITY_BACKGROUND);
13395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mThread.start();
13495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mBackgroundHandler = new BackgroundHandler(mThread.getLooper());
13595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
13695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // Only the owner can see all apps.
1372b45f8a6ce623012b2fc6237acd1bdc6ebe2c85cXiaohui Chen        mAdminRetrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES |
13895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                PackageManager.GET_DISABLED_COMPONENTS |
13995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
14095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mRetrieveFlags = PackageManager.GET_DISABLED_COMPONENTS |
14195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
14295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
14395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        /**
14495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * This is a trick to prevent the foreground thread from being delayed.
14595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * The problem is that Dalvik monitors are initially spin locks, to keep
14695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * them lightweight.  This leads to unfair contention -- Even though the
14795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * background thread only holds the lock for a short amount of time, if
14895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * it keeps running and locking again it can prevent the main thread from
14995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * acquiring its lock for a long time...  sometimes even > 5 seconds
15095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * (leading to an ANR).
15195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         *
15295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * Dalvik will promote a monitor to a "real" lock if it detects enough
15395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * contention on it.  It doesn't figure this out fast enough for us
15495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * here, though, so this little trick will force it to turn into a real
15595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         * lock immediately.
15695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler         */
15795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (mEntriesMap) {
15895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            try {
15995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mEntriesMap.wait(1);
16095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } catch (InterruptedException e) {
16195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
16295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
16395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
16495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
16595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public Looper getBackgroundLooper() {
16695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return mThread.getLooper();
16795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
16895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
16995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public Session newSession(Callbacks callbacks) {
17095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        Session s = new Session(callbacks);
17195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (mEntriesMap) {
17295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mSessions.add(s);
17395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
17495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return s;
17595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
17695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
17795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    void doResumeIfNeededLocked() {
17895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (mResumed) {
17995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return;
18095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
18195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mResumed = true;
18295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (mPackageIntentReceiver == null) {
18395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mPackageIntentReceiver = new PackageIntentReceiver();
18495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mPackageIntentReceiver.registerReceiver();
18595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
18695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mApplications = new ArrayList<ApplicationInfo>();
1872b45f8a6ce623012b2fc6237acd1bdc6ebe2c85cXiaohui Chen        for (UserInfo user : mUm.getProfiles(UserHandle.myUserId())) {
18895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            try {
18995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // If this user is new, it needs a map created.
1902b45f8a6ce623012b2fc6237acd1bdc6ebe2c85cXiaohui Chen                if (mEntriesMap.indexOfKey(user.id) < 0) {
1912b45f8a6ce623012b2fc6237acd1bdc6ebe2c85cXiaohui Chen                    mEntriesMap.put(user.id, new HashMap<String, AppEntry>());
19295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
19395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                @SuppressWarnings("unchecked")
19495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                ParceledListSlice<ApplicationInfo> list =
19595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mIpm.getInstalledApplications(
1962b45f8a6ce623012b2fc6237acd1bdc6ebe2c85cXiaohui Chen                                user.isAdmin() ? mAdminRetrieveFlags : mRetrieveFlags,
1972b45f8a6ce623012b2fc6237acd1bdc6ebe2c85cXiaohui Chen                                user.id);
19895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mApplications.addAll(list.getList());
19995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } catch (RemoteException e) {
20095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
20195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
20295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
20395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
20495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // If an interesting part of the configuration has changed, we
20595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // should completely reload the app entries.
20695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            clearEntries();
20795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        } else {
20895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            for (int i=0; i<mAppEntries.size(); i++) {
20995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mAppEntries.get(i).sizeStale = true;
21095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
21195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
21295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
21395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mHaveDisabledApps = false;
21495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        for (int i=0; i<mApplications.size(); i++) {
21595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            final ApplicationInfo info = mApplications.get(i);
21695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // Need to trim out any applications that are disabled by
21795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // something different than the user.
21895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (!info.enabled) {
21995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (info.enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
22095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mApplications.remove(i);
22195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    i--;
22295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    continue;
22395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
22495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mHaveDisabledApps = true;
22595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
22695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            int userId = UserHandle.getUserId(info.uid);
22795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            final AppEntry entry = mEntriesMap.get(userId).get(info.packageName);
22895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (entry != null) {
22995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                entry.info = info;
23095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
23195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
23295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (mAppEntries.size() > mApplications.size()) {
23395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // There are less apps now, some must have been uninstalled.
23495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            clearEntries();
23595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
23695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mCurComputingSizePkg = null;
23795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
23895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
23995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
24095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
24195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
24295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private void clearEntries() {
24395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        for (int i = 0; i < mEntriesMap.size(); i++) {
24495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mEntriesMap.valueAt(i).clear();
24595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
24695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mAppEntries.clear();
24795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
24895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
24995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public boolean haveDisabledApps() {
25095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return mHaveDisabledApps;
25195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
25295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
25395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    void doPauseIfNeededLocked() {
25495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (!mResumed) {
25595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return;
25695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
25795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        for (int i=0; i<mSessions.size(); i++) {
25895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (mSessions.get(i).mResumed) {
25995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return;
26095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
26195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
26295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        doPauseLocked();
26395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
26495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
26595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    void doPauseLocked() {
26695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        mResumed = false;
26795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (mPackageIntentReceiver != null) {
26895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mPackageIntentReceiver.unregisterReceiver();
26995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mPackageIntentReceiver = null;
27095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
27195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
27295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
27395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public AppEntry getEntry(String packageName, int userId) {
27495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (DEBUG_LOCKING) Log.v(TAG, "getEntry about to acquire lock...");
27595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (mEntriesMap) {
27695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            AppEntry entry = mEntriesMap.get(userId).get(packageName);
27795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (entry == null) {
27895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                ApplicationInfo info = getAppInfoLocked(packageName, userId);
27995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (info == null) {
28095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    try {
28195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        info = mIpm.getApplicationInfo(packageName, 0, userId);
28295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    } catch (RemoteException e) {
28395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        Log.w(TAG, "getEntry couldn't reach PackageManager", e);
28495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        return null;
28595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
28695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
287c1f24abd1098c2585bdb67b5ecb172433fdd2c90Jason Monk                if (info != null) {
288c1f24abd1098c2585bdb67b5ecb172433fdd2c90Jason Monk                    entry = getEntryLocked(info);
289c1f24abd1098c2585bdb67b5ecb172433fdd2c90Jason Monk                }
29095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
29195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG_LOCKING) Log.v(TAG, "...getEntry releasing lock");
29295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return entry;
29395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
29495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
29595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
29695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private ApplicationInfo getAppInfoLocked(String pkg, int userId) {
29795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        for (int i = 0; i < mApplications.size(); i++) {
29895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            ApplicationInfo info = mApplications.get(i);
29995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (pkg.equals(info.packageName)
30095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    && userId == UserHandle.getUserId(info.uid)) {
30195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return info;
30295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
30395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
30495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return null;
30595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
30695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
30795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public void ensureIcon(AppEntry entry) {
30895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (entry.icon != null) {
30995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return;
31095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
31195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (entry) {
31295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            entry.ensureIconLocked(mContext, mPm);
31395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
31495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
31595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
31695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public void requestSize(String packageName, int userId) {
31795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (DEBUG_LOCKING) Log.v(TAG, "requestSize about to acquire lock...");
31895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (mEntriesMap) {
31995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            AppEntry entry = mEntriesMap.get(userId).get(packageName);
32095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (entry != null) {
321e06b4d1d9f718b9fe02980fea794a36831a16db2Jeff Sharkey                mPm.getPackageSizeInfoAsUser(packageName, userId, mBackgroundHandler.mStatsObserver);
32295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
32395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG_LOCKING) Log.v(TAG, "...requestSize releasing lock");
32495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
32595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
32695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
32795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    long sumCacheSizes() {
32895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        long sum = 0;
32995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (DEBUG_LOCKING) Log.v(TAG, "sumCacheSizes about to acquire lock...");
33095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (mEntriesMap) {
33195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG_LOCKING) Log.v(TAG, "-> sumCacheSizes now has lock");
33295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            for (int i=mAppEntries.size()-1; i>=0; i--) {
33395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                sum += mAppEntries.get(i).cacheSize;
33495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
33595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG_LOCKING) Log.v(TAG, "...sumCacheSizes releasing lock");
33695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
33795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return sum;
33895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
33995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
34095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    int indexOfApplicationInfoLocked(String pkgName, int userId) {
34195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        for (int i=mApplications.size()-1; i>=0; i--) {
34295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            ApplicationInfo appInfo = mApplications.get(i);
34395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (appInfo.packageName.equals(pkgName)
34495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    && UserHandle.getUserId(appInfo.uid) == userId) {
34595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return i;
34695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
34795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
34895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return -1;
34995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
35095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
35195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    void addPackage(String pkgName, int userId) {
35295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        try {
35395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mEntriesMap) {
35495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (DEBUG_LOCKING) Log.v(TAG, "addPackage acquired lock");
35595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (DEBUG) Log.i(TAG, "Adding package " + pkgName);
35695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!mResumed) {
35795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    // If we are not resumed, we will do a full query the
35895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    // next time we resume, so there is no reason to do work
35995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    // here.
36095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: not resumed");
36195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    return;
36295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
36395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (indexOfApplicationInfoLocked(pkgName, userId) >= 0) {
36495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (DEBUG) Log.i(TAG, "Package already exists!");
36595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (DEBUG_LOCKING) Log.v(TAG, "addPackage release lock: already exists");
36695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    return;
36795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
36895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                ApplicationInfo info = mIpm.getApplicationInfo(pkgName,
3692b45f8a6ce623012b2fc6237acd1bdc6ebe2c85cXiaohui Chen                        mUm.isUserAdmin(userId) ? mAdminRetrieveFlags : mRetrieveFlags,
37095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        userId);
37195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (info == null) {
37295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    return;
37395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
37495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!info.enabled) {
37595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (info.enabledSetting
37695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
37795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        return;
37895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
37995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mHaveDisabledApps = true;
38095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
38195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mApplications.add(info);
38295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
38395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
38495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
38595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_LIST_CHANGED)) {
38695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_LIST_CHANGED);
38795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
38895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (DEBUG_LOCKING) Log.v(TAG, "addPackage releasing lock");
38995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
39095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        } catch (RemoteException e) {
39195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
39295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
39395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
394bdbb5a8d77865fd4bea7a5d14eabadba3270af2dTony Mantler    public void removePackage(String pkgName, int userId) {
39595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (mEntriesMap) {
39695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG_LOCKING) Log.v(TAG, "removePackage acquired lock");
39795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            int idx = indexOfApplicationInfoLocked(pkgName, userId);
39895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG) Log.i(TAG, "removePackage: " + pkgName + " @ " + idx);
39995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (idx >= 0) {
40095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                AppEntry entry = mEntriesMap.get(userId).get(pkgName);
40195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (DEBUG) Log.i(TAG, "removePackage: " + entry);
40295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (entry != null) {
40395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mEntriesMap.get(userId).remove(pkgName);
40495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mAppEntries.remove(entry);
40595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
40695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                ApplicationInfo info = mApplications.get(idx);
40795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mApplications.remove(idx);
40895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!info.enabled) {
40995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mHaveDisabledApps = false;
41095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (int i=0; i<mApplications.size(); i++) {
41195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (!mApplications.get(i).enabled) {
41295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            mHaveDisabledApps = true;
41395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            break;
41495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
41595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
41695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
41795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_LIST_CHANGED)) {
41895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_LIST_CHANGED);
41995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
42095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
42195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG_LOCKING) Log.v(TAG, "removePackage releasing lock");
42295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
42395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
42495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
42595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public void invalidatePackage(String pkgName, int userId) {
42695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        removePackage(pkgName, userId);
42795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        addPackage(pkgName, userId);
42895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
42995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
43095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private void addUser(int userId) {
431b87b0edfb36bccdbc5ca33d85e8917c6c7f23190Ricky Wai        final int profileIds[] = mUm.getProfileIdsWithDisabled(UserHandle.myUserId());
432b87b0edfb36bccdbc5ca33d85e8917c6c7f23190Ricky Wai        if (ArrayUtils.contains(profileIds, userId)) {
43395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mEntriesMap) {
43495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mEntriesMap.put(userId, new HashMap<String, AppEntry>());
43595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (mResumed) {
43695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    // If resumed, Manually pause, then cause a resume to repopulate the app list.
43795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    // This is the simplest way to reload the packages so that the new user
43895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    // is included.  Otherwise the list will be repopulated on next resume.
43995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    doPauseLocked();
44095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    doResumeIfNeededLocked();
44195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
44295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_LIST_CHANGED)) {
44395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_LIST_CHANGED);
44495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
44595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
44695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
44795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
44895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
44995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private void removeUser(int userId) {
45095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (mEntriesMap) {
45195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            HashMap<String, AppEntry> userMap = mEntriesMap.get(userId);
45295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (userMap != null) {
45395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                for (AppEntry appEntry : userMap.values()) {
45495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mAppEntries.remove(appEntry);
45595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mApplications.remove(appEntry.info);
45695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
45795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mEntriesMap.remove(userId);
45895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_LIST_CHANGED)) {
45995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_LIST_CHANGED);
46095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
46195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
46295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
46395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
46495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
46595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private AppEntry getEntryLocked(ApplicationInfo info) {
46695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        int userId = UserHandle.getUserId(info.uid);
46795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        AppEntry entry = mEntriesMap.get(userId).get(info.packageName);
46895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (DEBUG) Log.i(TAG, "Looking up entry of pkg " + info.packageName + ": " + entry);
46995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (entry == null) {
47095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG) Log.i(TAG, "Creating AppEntry for " + info.packageName);
47195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            entry = new AppEntry(mContext, info, mCurId++);
47295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mEntriesMap.get(userId).put(info.packageName, entry);
47395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mAppEntries.add(entry);
47495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        } else if (entry.info != info) {
47595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            entry.info = info;
47695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
47795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return entry;
47895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
47995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
48095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    // --------------------------------------------------------------
48195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
48295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private long getTotalInternalSize(PackageStats ps) {
48395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (ps != null) {
48495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return ps.codeSize + ps.dataSize;
48595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
48695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return SIZE_INVALID;
48795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
48895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
48995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private long getTotalExternalSize(PackageStats ps) {
49095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (ps != null) {
49195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // We also include the cache size here because for non-emulated
49295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // we don't automtically clean cache files.
49395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return ps.externalCodeSize + ps.externalDataSize
49495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    + ps.externalCacheSize
49595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    + ps.externalMediaSize + ps.externalObbSize;
49695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
49795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return SIZE_INVALID;
49895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
49995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
50095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private String getSizeStr(long size) {
50195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        if (size >= 0) {
50295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return Formatter.formatFileSize(mContext, size);
50395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
50495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        return null;
50595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
50695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
50795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    void rebuildActiveSessions() {
50895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        synchronized (mEntriesMap) {
50995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (!mSessionsChanged) {
51095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return;
51195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
51295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mActiveSessions.clear();
51395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            for (int i=0; i<mSessions.size(); i++) {
51495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                Session s = mSessions.get(i);
51595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (s.mResumed) {
51695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mActiveSessions.add(s);
51795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
51895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
51995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
52095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
52195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
522e3fd6de9d69e6650f8838e2aee69531fabbe99caJason Monk    public static String normalize(String str) {
523e3fd6de9d69e6650f8838e2aee69531fabbe99caJason Monk        String tmp = Normalizer.normalize(str, Form.NFD);
524e3fd6de9d69e6650f8838e2aee69531fabbe99caJason Monk        return REMOVE_DIACRITICALS_PATTERN.matcher(tmp)
525e3fd6de9d69e6650f8838e2aee69531fabbe99caJason Monk                .replaceAll("").toLowerCase();
526e3fd6de9d69e6650f8838e2aee69531fabbe99caJason Monk    }
527e3fd6de9d69e6650f8838e2aee69531fabbe99caJason Monk
52895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public class Session {
52995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        final Callbacks mCallbacks;
53095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        boolean mResumed;
53195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
53295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // Rebuilding of app list.  Synchronized on mRebuildSync.
53395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        final Object mRebuildSync = new Object();
53495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        boolean mRebuildRequested;
53595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        boolean mRebuildAsync;
53695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        AppFilter mRebuildFilter;
53795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        Comparator<AppEntry> mRebuildComparator;
53895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        ArrayList<AppEntry> mRebuildResult;
53995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        ArrayList<AppEntry> mLastAppList;
540b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk        boolean mRebuildForeground;
54195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
54295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        Session(Callbacks callbacks) {
54395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mCallbacks = callbacks;
54495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
54595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
54695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void resume() {
54795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG_LOCKING) Log.v(TAG, "resume about to acquire lock...");
54895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mEntriesMap) {
54995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!mResumed) {
55095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mResumed = true;
55195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mSessionsChanged = true;
55295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    doResumeIfNeededLocked();
55395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
55495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
55595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG_LOCKING) Log.v(TAG, "...resume releasing lock");
55695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
55795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
55895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void pause() {
55995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG_LOCKING) Log.v(TAG, "pause about to acquire lock...");
56095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mEntriesMap) {
56195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (mResumed) {
56295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mResumed = false;
56395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mSessionsChanged = true;
56495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mBackgroundHandler.removeMessages(BackgroundHandler.MSG_REBUILD_LIST, this);
56595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    doPauseIfNeededLocked();
56695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
56795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (DEBUG_LOCKING) Log.v(TAG, "...pause releasing lock");
56895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
56995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
57095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
57195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public ArrayList<AppEntry> getAllApps() {
57295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mEntriesMap) {
57395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return new ArrayList<>(mAppEntries);
57495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
57595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
57695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
57795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // Creates a new list of app entries with the given filter and comparator.
57895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public ArrayList<AppEntry> rebuild(AppFilter filter, Comparator<AppEntry> comparator) {
579b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk            return rebuild(filter, comparator, true);
580b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk        }
581b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk
582b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk        public ArrayList<AppEntry> rebuild(AppFilter filter, Comparator<AppEntry> comparator,
583b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                boolean foreground) {
58495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mRebuildSync) {
58595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                synchronized (mEntriesMap) {
58695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mRebuildingSessions.add(this);
58795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mRebuildRequested = true;
58895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mRebuildAsync = false;
58995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mRebuildFilter = filter;
59095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mRebuildComparator = comparator;
591b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                    mRebuildForeground = foreground;
59295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mRebuildResult = null;
59395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_REBUILD_LIST)) {
59495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        Message msg = mBackgroundHandler.obtainMessage(
59595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                BackgroundHandler.MSG_REBUILD_LIST);
59695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mBackgroundHandler.sendMessage(msg);
59795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
59895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
59995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
60095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // We will wait for .25s for the list to be built.
60195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                long waitend = SystemClock.uptimeMillis()+250;
60295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
60395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                while (mRebuildResult == null) {
60495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    long now = SystemClock.uptimeMillis();
60595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (now >= waitend) {
60695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        break;
60795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
60895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    try {
60995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mRebuildSync.wait(waitend - now);
61095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    } catch (InterruptedException e) {
61195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
61295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
61395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
61495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mRebuildAsync = true;
61595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
61695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return mRebuildResult;
61795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
61895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
61995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
62095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void handleRebuildList() {
62195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            AppFilter filter;
62295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            Comparator<AppEntry> comparator;
62395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mRebuildSync) {
62495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!mRebuildRequested) {
62595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    return;
62695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
62795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
62895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                filter = mRebuildFilter;
62995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                comparator = mRebuildComparator;
63095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mRebuildRequested = false;
63195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mRebuildFilter = null;
63295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mRebuildComparator = null;
633b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                if (mRebuildForeground) {
634b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                    Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
635b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                    mRebuildForeground = false;
636b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                }
63795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
63895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
63995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (filter != null) {
64095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                filter.init();
64195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
64295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
64395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            List<AppEntry> apps;
64495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mEntriesMap) {
64595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                apps = new ArrayList<>(mAppEntries);
64695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
64795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
64895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            ArrayList<AppEntry> filteredApps = new ArrayList<AppEntry>();
64995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (DEBUG) Log.i(TAG, "Rebuilding...");
65095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            for (int i=0; i<apps.size(); i++) {
65195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                AppEntry entry = apps.get(i);
6527e01af424355b5bbac64126fef4e3d37c9c41dd7Svetoslav Ganov                if (entry != null && (filter == null || filter.filterApp(entry))) {
65395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    synchronized (mEntriesMap) {
65495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (DEBUG_LOCKING) Log.v(TAG, "rebuild acquired lock");
655b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                        if (comparator != null) {
656b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                            // Only need the label if we are going to be sorting.
657b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                            entry.ensureLabel(mContext);
658b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                        }
65995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (DEBUG) Log.i(TAG, "Using " + entry.info.packageName + ": " + entry);
66095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        filteredApps.add(entry);
66195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (DEBUG_LOCKING) Log.v(TAG, "rebuild releasing lock");
66295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
66395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
66495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
66595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
666b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk            if (comparator != null) {
667b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk                Collections.sort(filteredApps, comparator);
668b0ae8f820927fc6c039b4e4efd6d3f15c1a6a141Jason Monk            }
66995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
67095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mRebuildSync) {
67195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!mRebuildRequested) {
67295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mLastAppList = filteredApps;
67395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (!mRebuildAsync) {
67495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mRebuildResult = filteredApps;
67595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mRebuildSync.notifyAll();
67695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    } else {
67795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (!mMainHandler.hasMessages(MainHandler.MSG_REBUILD_COMPLETE, this)) {
67895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            Message msg = mMainHandler.obtainMessage(
67995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    MainHandler.MSG_REBUILD_COMPLETE, this);
68095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            mMainHandler.sendMessage(msg);
68195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
68295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
68395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
68495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
68595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
68695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
68795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
68895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
68995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void release() {
69095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            pause();
69195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mEntriesMap) {
69295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                mSessions.remove(this);
69395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
69495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
69595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
69695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
69795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    class MainHandler extends Handler {
69895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_REBUILD_COMPLETE = 1;
69995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_PACKAGE_LIST_CHANGED = 2;
70095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_PACKAGE_ICON_CHANGED = 3;
70195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_PACKAGE_SIZE_CHANGED = 4;
70295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_ALL_SIZES_COMPUTED = 5;
70395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_RUNNING_STATE_CHANGED = 6;
70495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_LAUNCHER_INFO_CHANGED = 7;
70595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_LOAD_ENTRIES_COMPLETE = 8;
70695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
7072a5d79aa6fd882ef6f46439f5156c516f173f06aJason Monk        public MainHandler(Looper looper) {
7082a5d79aa6fd882ef6f46439f5156c516f173f06aJason Monk            super(looper);
7092a5d79aa6fd882ef6f46439f5156c516f173f06aJason Monk        }
7102a5d79aa6fd882ef6f46439f5156c516f173f06aJason Monk
71195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
71295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void handleMessage(Message msg) {
71395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            rebuildActiveSessions();
71495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            switch (msg.what) {
71595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_REBUILD_COMPLETE: {
71695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    Session s = (Session)msg.obj;
71795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (mActiveSessions.contains(s)) {
71895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        s.mCallbacks.onRebuildComplete(s.mLastAppList);
71995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
72095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
72195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_PACKAGE_LIST_CHANGED: {
72295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (int i=0; i<mActiveSessions.size(); i++) {
72395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mActiveSessions.get(i).mCallbacks.onPackageListChanged();
72495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
72595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
72695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_PACKAGE_ICON_CHANGED: {
72795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (int i=0; i<mActiveSessions.size(); i++) {
72895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mActiveSessions.get(i).mCallbacks.onPackageIconChanged();
72995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
73095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
73195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_PACKAGE_SIZE_CHANGED: {
73295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (int i=0; i<mActiveSessions.size(); i++) {
73395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mActiveSessions.get(i).mCallbacks.onPackageSizeChanged(
73495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                (String)msg.obj);
73595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
73695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
73795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_ALL_SIZES_COMPUTED: {
73895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (int i=0; i<mActiveSessions.size(); i++) {
73995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mActiveSessions.get(i).mCallbacks.onAllSizesComputed();
74095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
74195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
74295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_RUNNING_STATE_CHANGED: {
74395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (int i=0; i<mActiveSessions.size(); i++) {
74495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mActiveSessions.get(i).mCallbacks.onRunningStateChanged(
74595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                msg.arg1 != 0);
74695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
74795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
74895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_LAUNCHER_INFO_CHANGED: {
74995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (int i=0; i<mActiveSessions.size(); i++) {
75095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mActiveSessions.get(i).mCallbacks.onLauncherInfoChanged();
75195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
75295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
75395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_LOAD_ENTRIES_COMPLETE: {
75495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (int i=0; i<mActiveSessions.size(); i++) {
75595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mActiveSessions.get(i).mCallbacks.onLoadEntriesCompleted();
75695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
75795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
75895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
75995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
76095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
76195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
76295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private class BackgroundHandler extends Handler {
76395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_REBUILD_LIST = 1;
76495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_LOAD_ENTRIES = 2;
76595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_LOAD_ICONS = 3;
76695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_LOAD_SIZES = 4;
76795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        static final int MSG_LOAD_LAUNCHER = 5;
76895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
76995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        boolean mRunning;
77095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
77195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        BackgroundHandler(Looper looper) {
77295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            super(looper);
77395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
77495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
77595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
77695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void handleMessage(Message msg) {
77795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // Always try rebuilding list first thing, if needed.
77895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            ArrayList<Session> rebuildingSessions = null;
77995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            synchronized (mEntriesMap) {
78095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (mRebuildingSessions.size() > 0) {
78195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    rebuildingSessions = new ArrayList<Session>(mRebuildingSessions);
78295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    mRebuildingSessions.clear();
78395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
78495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
78595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (rebuildingSessions != null) {
78695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                for (int i=0; i<rebuildingSessions.size(); i++) {
78795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    rebuildingSessions.get(i).handleRebuildList();
78895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
78995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
79095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
79195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            switch (msg.what) {
79295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_REBUILD_LIST: {
79395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
79495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_LOAD_ENTRIES: {
79595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    int numDone = 0;
79695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    synchronized (mEntriesMap) {
79795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ENTRIES acquired lock");
79895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        for (int i = 0; i < mApplications.size() && numDone < 6; i++) {
79995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            if (!mRunning) {
80095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                mRunning = true;
80195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                Message m = mMainHandler.obtainMessage(
80295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                        MainHandler.MSG_RUNNING_STATE_CHANGED, 1);
80395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                mMainHandler.sendMessage(m);
80495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            }
80595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            ApplicationInfo info = mApplications.get(i);
80695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            int userId = UserHandle.getUserId(info.uid);
80795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            if (mEntriesMap.get(userId).get(info.packageName) == null) {
80895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                numDone++;
80995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                getEntryLocked(info);
81095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            }
8116ff98ce2c89f94d47566de3426567748fad97814Jason Monk                            if (userId != 0 && mEntriesMap.indexOfKey(0) >= 0) {
8126ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                // If this app is for a profile and we are on the owner, remove
8136ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                // the owner entry if it isn't installed.  This will prevent
8146ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                // duplicates of work only apps showing up as 'not installed
8156ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                // for this user'.
8166ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                // Note: This depends on us traversing the users in order, which
8176ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                // happens because of the way we generate the list in
8186ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                // doResumeIfNeededLocked.
8196ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                AppEntry entry = mEntriesMap.get(0).get(info.packageName);
8206ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                if (entry != null &&
8216ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                        (entry.info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
8226ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                    mEntriesMap.get(0).remove(info.packageName);
8236ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                    mAppEntries.remove(entry);
8246ff98ce2c89f94d47566de3426567748fad97814Jason Monk                                }
8256ff98ce2c89f94d47566de3426567748fad97814Jason Monk                            }
82695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
82795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ENTRIES releasing lock");
82895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
82995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
83095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (numDone >= 6) {
83195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        sendEmptyMessage(MSG_LOAD_ENTRIES);
83295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    } else {
83395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (!mMainHandler.hasMessages(MainHandler.MSG_LOAD_ENTRIES_COMPLETE)) {
83495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            mMainHandler.sendEmptyMessage(MainHandler.MSG_LOAD_ENTRIES_COMPLETE);
83595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
83695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        sendEmptyMessage(MSG_LOAD_LAUNCHER);
83795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
83895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
83995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_LOAD_LAUNCHER: {
84095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    Intent launchIntent = new Intent(Intent.ACTION_MAIN, null)
84195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            .addCategory(Intent.CATEGORY_LAUNCHER);
84295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
84395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (int i = 0; i < mEntriesMap.size(); i++) {
84495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        int userId = mEntriesMap.keyAt(i);
845186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                        // If we do not specify MATCH_DIRECT_BOOT_AWARE or
846186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                        // MATCH_DIRECT_BOOT_UNAWARE, system will derive and update the flags
847186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                        // according to the user's lock state. When the user is locked, components
848186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                        // with ComponentInfo#directBootAware == false will be filtered. We should
849186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                        // explicitly include both direct boot aware and unaware components here.
850186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                        List<ResolveInfo> intents = mPm.queryIntentActivitiesAsUser(
851186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                                launchIntent,
852186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                                PackageManager.GET_DISABLED_COMPONENTS
853186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                                        | PackageManager.MATCH_DIRECT_BOOT_AWARE
854186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
855186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                                userId
856186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau                        );
85795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        synchronized (mEntriesMap) {
85895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_LAUNCHER acquired lock");
85995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            HashMap<String, AppEntry> userEntries = mEntriesMap.valueAt(i);
86095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            final int N = intents.size();
86195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            for (int j = 0; j < N; j++) {
86295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                String packageName = intents.get(j).activityInfo.packageName;
86395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                AppEntry entry = userEntries.get(packageName);
86495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                if (entry != null) {
86595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    entry.hasLauncherEntry = true;
86695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                } else {
86795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    Log.w(TAG, "Cannot find pkg: " + packageName
86895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                            + " on user " + userId);
86995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                }
87095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            }
87195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_LAUNCHER releasing lock");
87295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
87395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
87495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
87595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (!mMainHandler.hasMessages(MainHandler.MSG_LAUNCHER_INFO_CHANGED)) {
87695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mMainHandler.sendEmptyMessage(MainHandler.MSG_LAUNCHER_INFO_CHANGED);
87795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
87895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    sendEmptyMessage(MSG_LOAD_ICONS);
87995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
88095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_LOAD_ICONS: {
88195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    int numDone = 0;
88295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    synchronized (mEntriesMap) {
88395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ICONS acquired lock");
88495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        for (int i=0; i<mAppEntries.size() && numDone<2; i++) {
88595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            AppEntry entry = mAppEntries.get(i);
88695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            if (entry.icon == null || !entry.mounted) {
88795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                synchronized (entry) {
88895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    if (entry.ensureIconLocked(mContext, mPm)) {
88995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                        if (!mRunning) {
89095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                            mRunning = true;
89195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                            Message m = mMainHandler.obtainMessage(
89295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                                    MainHandler.MSG_RUNNING_STATE_CHANGED, 1);
89395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                            mMainHandler.sendMessage(m);
89495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                        }
89595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                        numDone++;
89695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    }
89795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                }
89895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            }
89995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
90095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ICONS releasing lock");
90195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
90295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (numDone > 0) {
90395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (!mMainHandler.hasMessages(MainHandler.MSG_PACKAGE_ICON_CHANGED)) {
90495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            mMainHandler.sendEmptyMessage(MainHandler.MSG_PACKAGE_ICON_CHANGED);
90595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
90695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
90795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (numDone >= 2) {
90895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        sendEmptyMessage(MSG_LOAD_ICONS);
90995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    } else {
91095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        sendEmptyMessage(MSG_LOAD_SIZES);
91195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
91295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
91395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                case MSG_LOAD_SIZES: {
91495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    synchronized (mEntriesMap) {
91595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES acquired lock");
91695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (mCurComputingSizePkg != null) {
91795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing: currently computing");
91895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            return;
91995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
92095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
92195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        long now = SystemClock.uptimeMillis();
92295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        for (int i=0; i<mAppEntries.size(); i++) {
92395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            AppEntry entry = mAppEntries.get(i);
92495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            if (entry.size == SIZE_UNKNOWN || entry.sizeStale) {
92595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                if (entry.sizeLoadStart == 0 ||
92695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                        (entry.sizeLoadStart < (now-20*1000))) {
92795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    if (!mRunning) {
92895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                        mRunning = true;
92995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                        Message m = mMainHandler.obtainMessage(
93095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                                MainHandler.MSG_RUNNING_STATE_CHANGED, 1);
93195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                        mMainHandler.sendMessage(m);
93295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    }
93395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    entry.sizeLoadStart = now;
93495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    mCurComputingSizePkg = entry.info.packageName;
93595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    mCurComputingSizeUserId = UserHandle.getUserId(entry.info.uid);
936e06b4d1d9f718b9fe02980fea794a36831a16db2Jeff Sharkey                                    mPm.getPackageSizeInfoAsUser(mCurComputingSizePkg,
93795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                            mCurComputingSizeUserId, mStatsObserver);
93895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                }
93995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing: now computing");
94095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                return;
94195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            }
94295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
94395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (!mMainHandler.hasMessages(MainHandler.MSG_ALL_SIZES_COMPUTED)) {
94495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            mMainHandler.sendEmptyMessage(MainHandler.MSG_ALL_SIZES_COMPUTED);
94595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            mRunning = false;
94695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            Message m = mMainHandler.obtainMessage(
94795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    MainHandler.MSG_RUNNING_STATE_CHANGED, 0);
94895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            mMainHandler.sendMessage(m);
94995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
95095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing lock");
95195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
95295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } break;
95395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
95495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
95595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
95695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        final IPackageStatsObserver.Stub mStatsObserver = new IPackageStatsObserver.Stub() {
95795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            public void onGetStatsCompleted(PackageStats stats, boolean succeeded) {
95895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                boolean sizeChanged = false;
95995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                synchronized (mEntriesMap) {
96095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (DEBUG_LOCKING) Log.v(TAG, "onGetStatsCompleted acquired lock");
96195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    HashMap<String, AppEntry> userMap = mEntriesMap.get(stats.userHandle);
96295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (userMap == null) {
96395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        // The user must have been removed.
96495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        return;
96595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
96695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    AppEntry entry = userMap.get(stats.packageName);
96795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (entry != null) {
96895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        synchronized (entry) {
96995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            entry.sizeStale = false;
97095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            entry.sizeLoadStart = 0;
97195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            long externalCodeSize = stats.externalCodeSize
97295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    + stats.externalObbSize;
97395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            long externalDataSize = stats.externalDataSize
97495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    + stats.externalMediaSize;
97595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            long newSize = externalCodeSize + externalDataSize
97695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    + getTotalInternalSize(stats);
97795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            if (entry.size != newSize ||
97895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    entry.cacheSize != stats.cacheSize ||
97995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    entry.codeSize != stats.codeSize ||
98095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    entry.dataSize != stats.dataSize ||
98195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    entry.externalCodeSize != externalCodeSize ||
98295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    entry.externalDataSize != externalDataSize ||
98395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    entry.externalCacheSize != stats.externalCacheSize) {
98495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.size = newSize;
98595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.cacheSize = stats.cacheSize;
98695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.codeSize = stats.codeSize;
98795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.dataSize = stats.dataSize;
98895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.externalCodeSize = externalCodeSize;
98995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.externalDataSize = externalDataSize;
99095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.externalCacheSize = stats.externalCacheSize;
99195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.sizeStr = getSizeStr(entry.size);
99295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.internalSize = getTotalInternalSize(stats);
99395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.internalSizeStr = getSizeStr(entry.internalSize);
99495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.externalSize = getTotalExternalSize(stats);
99595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                entry.externalSizeStr = getSizeStr(entry.externalSize);
99695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                if (DEBUG) Log.i(TAG, "Set size of " + entry.label + " " + entry
99795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                        + ": " + entry.sizeStr);
99895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                sizeChanged = true;
99995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            }
100095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
100195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        if (sizeChanged) {
100295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            Message msg = mMainHandler.obtainMessage(
100395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                                    MainHandler.MSG_PACKAGE_SIZE_CHANGED, stats.packageName);
100495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            mMainHandler.sendMessage(msg);
100595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
100695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
100795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (mCurComputingSizePkg != null
100895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            && (mCurComputingSizePkg.equals(stats.packageName)
100995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            && mCurComputingSizeUserId == stats.userHandle)) {
101095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        mCurComputingSizePkg = null;
101195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        sendEmptyMessage(MSG_LOAD_SIZES);
101295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
101395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    if (DEBUG_LOCKING) Log.v(TAG, "onGetStatsCompleted releasing lock");
101495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
101595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
101695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        };
101795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
101895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
101995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    /**
102095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler     * Receives notifications when applications are added/removed.
102195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler     */
102295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    private class PackageIntentReceiver extends BroadcastReceiver {
102395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void registerReceiver() {
102495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
102595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
102695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
102795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            filter.addDataScheme("package");
102895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mContext.registerReceiver(this, filter);
102995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // Register for events related to sdcard installation.
103095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            IntentFilter sdFilter = new IntentFilter();
103195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
103295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
103395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mContext.registerReceiver(this, sdFilter);
103495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // Register for events related to user creation/deletion.
103595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            IntentFilter userFilter = new IntentFilter();
103695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            userFilter.addAction(Intent.ACTION_USER_ADDED);
103795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            userFilter.addAction(Intent.ACTION_USER_REMOVED);
103895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mContext.registerReceiver(this, userFilter);
103995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
104095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void unregisterReceiver() {
104195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mContext.unregisterReceiver(this);
104295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
104395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
104495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void onReceive(Context context, Intent intent) {
104595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            String actionStr = intent.getAction();
104695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (Intent.ACTION_PACKAGE_ADDED.equals(actionStr)) {
104795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                Uri data = intent.getData();
104895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                String pkgName = data.getEncodedSchemeSpecificPart();
104995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                for (int i = 0; i < mEntriesMap.size(); i++) {
105095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    addPackage(pkgName, mEntriesMap.keyAt(i));
105195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
105295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } else if (Intent.ACTION_PACKAGE_REMOVED.equals(actionStr)) {
105395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                Uri data = intent.getData();
105495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                String pkgName = data.getEncodedSchemeSpecificPart();
105595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                for (int i = 0; i < mEntriesMap.size(); i++) {
105695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    removePackage(pkgName, mEntriesMap.keyAt(i));
105795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
105895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } else if (Intent.ACTION_PACKAGE_CHANGED.equals(actionStr)) {
105995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                Uri data = intent.getData();
106095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                String pkgName = data.getEncodedSchemeSpecificPart();
106195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                for (int i = 0; i < mEntriesMap.size(); i++) {
106295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    invalidatePackage(pkgName, mEntriesMap.keyAt(i));
106395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
106495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr) ||
106595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(actionStr)) {
106695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // When applications become available or unavailable (perhaps because
106795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // the SD card was inserted or ejected) we need to refresh the
106895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // AppInfo with new label, icon and size information as appropriate
106995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // given the newfound (un)availability of the application.
107095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // A simple way to do that is to treat the refresh as a package
107195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // removal followed by a package addition.
107295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                String pkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
107395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (pkgList == null || pkgList.length == 0) {
107495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    // Ignore
107595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    return;
107695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
107795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                boolean avail = Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr);
107895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (avail) {
107995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    for (String pkgName : pkgList) {
108095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        for (int i = 0; i < mEntriesMap.size(); i++) {
108195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            invalidatePackage(pkgName, mEntriesMap.keyAt(i));
108295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                        }
108395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    }
108495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
108595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } else if (Intent.ACTION_USER_ADDED.equals(actionStr)) {
108695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                addUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL));
108795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } else if (Intent.ACTION_USER_REMOVED.equals(actionStr)) {
108895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL));
108995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
109095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
109195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
109295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
109395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public interface Callbacks {
109495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void onRunningStateChanged(boolean running);
109595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void onPackageListChanged();
109695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void onRebuildComplete(ArrayList<AppEntry> apps);
109795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void onPackageIconChanged();
109895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void onPackageSizeChanged(String packageName);
109995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void onAllSizesComputed();
110095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void onLauncherInfoChanged();
110195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void onLoadEntriesCompleted();
110295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
110395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
110495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static class SizeInfo {
110595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long cacheSize;
110695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long codeSize;
110795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long dataSize;
110895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long externalCodeSize;
110995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long externalDataSize;
111095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
111195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // This is the part of externalDataSize that is in the cache
111295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // section of external storage.  Note that we don't just combine
111395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // this with cacheSize because currently the platform can't
111495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // automatically trim this data when needed, so it is something
111595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // the user may need to manage.  The externalDataSize also includes
111695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // this value, since what this is here is really the part of
111795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // externalDataSize that we can just consider to be "cache" files
111895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // for purposes of cleaning them up in the app details UI.
111995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long externalCacheSize;
112095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
112195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
112295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static class AppEntry extends SizeInfo {
112395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public final File apkFile;
112495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public final long id;
112595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public String label;
112695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long size;
112795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long internalSize;
112895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long externalSize;
112995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
113095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean mounted;
113195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
1132186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau        /**
1133186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau         * Setting this to {@code true} prevents the entry to be filtered by
1134186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau         * {@link #FILTER_DOWNLOADED_AND_LAUNCHER}.
1135186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau         */
113695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean hasLauncherEntry;
113795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
113895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public String getNormalizedLabel() {
113995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (normalizedLabel != null) {
114095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return normalizedLabel;
114195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
114295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            normalizedLabel = normalize(label);
114395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return normalizedLabel;
114495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
114595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
114695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // Need to synchronize on 'this' for the following.
114795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public ApplicationInfo info;
114895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public Drawable icon;
114995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public String sizeStr;
115095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public String internalSizeStr;
115195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public String externalSizeStr;
115295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean sizeStale;
115395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public long sizeLoadStart;
115495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
115595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public String normalizedLabel;
115695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
115795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        // A location where extra info can be placed to be used by custom filters.
115895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public Object extraInfo;
115995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
116095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        AppEntry(Context context, ApplicationInfo info, long id) {
116195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            apkFile = new File(info.sourceDir);
116295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            this.id = id;
116395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            this.info = info;
116495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            this.size = SIZE_UNKNOWN;
116595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            this.sizeStale = true;
116695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            ensureLabel(context);
116795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
116895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
1169bdbb5a8d77865fd4bea7a5d14eabadba3270af2dTony Mantler        public void ensureLabel(Context context) {
117095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (this.label == null || !this.mounted) {
117195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (!this.apkFile.exists()) {
117295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    this.mounted = false;
117395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    this.label = info.packageName;
117495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } else {
117595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    this.mounted = true;
117695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    CharSequence label = info.loadLabel(context.getPackageManager());
117795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    this.label = label != null ? label.toString() : info.packageName;
117895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
117995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
118095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
118195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
118295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        boolean ensureIconLocked(Context context, PackageManager pm) {
118395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (this.icon == null) {
118495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (this.apkFile.exists()) {
118595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    this.icon = getBadgedIcon(pm);
118695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    return true;
118795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                } else {
118895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    this.mounted = false;
118995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    this.icon = context.getDrawable(
119095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                            com.android.internal.R.drawable.sym_app_on_sd_unavailable_icon);
119195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
119295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } else if (!this.mounted) {
119395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // If the app wasn't mounted but is now mounted, reload
119495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                // its icon.
119595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                if (this.apkFile.exists()) {
119695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    this.mounted = true;
119795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    this.icon = getBadgedIcon(pm);
119895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    return true;
119995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                }
120095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
120195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return false;
120295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
120395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
120495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        private Drawable getBadgedIcon(PackageManager pm) {
120595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            // Do badging ourself so that it comes from the user of the app not the current user.
120695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return pm.getUserBadgedIcon(pm.loadUnbadgedItemIcon(info, info),
120795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                    new UserHandle(UserHandle.getUserId(info.uid)));
120895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
120995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
1210bdbb5a8d77865fd4bea7a5d14eabadba3270af2dTony Mantler        public String getVersion(Context context) {
1211bdbb5a8d77865fd4bea7a5d14eabadba3270af2dTony Mantler            try {
1212bdbb5a8d77865fd4bea7a5d14eabadba3270af2dTony Mantler                return context.getPackageManager().getPackageInfo(info.packageName, 0).versionName;
1213bdbb5a8d77865fd4bea7a5d14eabadba3270af2dTony Mantler            } catch (PackageManager.NameNotFoundException e) {
1214bdbb5a8d77865fd4bea7a5d14eabadba3270af2dTony Mantler                return "";
1215bdbb5a8d77865fd4bea7a5d14eabadba3270af2dTony Mantler            }
1216bdbb5a8d77865fd4bea7a5d14eabadba3270af2dTony Mantler        }
121795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
121895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
121954f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung    /**
122054f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung     * Compare by label, then package name, then uid.
122154f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung     */
122295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final Comparator<AppEntry> ALPHA_COMPARATOR = new Comparator<AppEntry>() {
122395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        private final Collator sCollator = Collator.getInstance();
122495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
122595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public int compare(AppEntry object1, AppEntry object2) {
122654f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            int compareResult = sCollator.compare(object1.label, object2.label);
122754f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            if (compareResult != 0) {
122854f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung                return compareResult;
122954f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            }
123054f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            if (object1.info != null && object2.info != null) {
123154f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung                compareResult =
123254f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung                    sCollator.compare(object1.info.packageName, object2.info.packageName);
123354f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung                if (compareResult != 0) {
123454f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung                    return compareResult;
123554f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung                }
123654f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            }
123754f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            return object1.info.uid - object2.info.uid;
123895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
123995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
124095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
124195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final Comparator<AppEntry> SIZE_COMPARATOR
124295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            = new Comparator<AppEntry>() {
124395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
124495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public int compare(AppEntry object1, AppEntry object2) {
124595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (object1.size < object2.size) return 1;
124695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (object1.size > object2.size) return -1;
124754f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            return ALPHA_COMPARATOR.compare(object1, object2);
124895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
124995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
125095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
125195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final Comparator<AppEntry> INTERNAL_SIZE_COMPARATOR
125295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            = new Comparator<AppEntry>() {
125395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
125495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public int compare(AppEntry object1, AppEntry object2) {
125595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (object1.internalSize < object2.internalSize) return 1;
125695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (object1.internalSize > object2.internalSize) return -1;
125754f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            return ALPHA_COMPARATOR.compare(object1, object2);
125895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
125995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
126095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
126195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final Comparator<AppEntry> EXTERNAL_SIZE_COMPARATOR
126295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            = new Comparator<AppEntry>() {
126395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
126495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public int compare(AppEntry object1, AppEntry object2) {
126595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (object1.externalSize < object2.externalSize) return 1;
126695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if (object1.externalSize > object2.externalSize) return -1;
126754f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            return ALPHA_COMPARATOR.compare(object1, object2);
126895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
126995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
127095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
127195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public interface AppFilter {
127295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        void init();
127395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        boolean filterApp(AppEntry info);
127495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
127595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
127695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final AppFilter FILTER_PERSONAL = new AppFilter() {
127795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        private int mCurrentUser;
127895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
127995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
128095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mCurrentUser = ActivityManager.getCurrentUser();
128195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
128295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
128395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
128495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry entry) {
128595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return UserHandle.getUserId(entry.info.uid) == mCurrentUser;
128695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
128795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
128895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
128954f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung    public static final AppFilter FILTER_WITHOUT_DISABLED_UNTIL_USED = new AppFilter() {
1290b6d17ee7aeace3c2b2443c94c9ad4ff50f82e8deZach Johnson        public void init() {
129154f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            // do nothings
1292b6d17ee7aeace3c2b2443c94c9ad4ff50f82e8deZach Johnson        }
1293b6d17ee7aeace3c2b2443c94c9ad4ff50f82e8deZach Johnson
1294b6d17ee7aeace3c2b2443c94c9ad4ff50f82e8deZach Johnson        @Override
1295b6d17ee7aeace3c2b2443c94c9ad4ff50f82e8deZach Johnson        public boolean filterApp(AppEntry entry) {
129654f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung            return entry.info.enabledSetting
129754f7d9bfafcd355ecb610eb45d4d31dc7601627dKeith Cheung                    != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
1298b6d17ee7aeace3c2b2443c94c9ad4ff50f82e8deZach Johnson        }
1299b6d17ee7aeace3c2b2443c94c9ad4ff50f82e8deZach Johnson    };
1300b6d17ee7aeace3c2b2443c94c9ad4ff50f82e8deZach Johnson
130195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final AppFilter FILTER_WORK = new AppFilter() {
130295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        private int mCurrentUser;
130395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
130495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
130595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mCurrentUser = ActivityManager.getCurrentUser();
130695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
130795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
130895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
130995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry entry) {
131095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return UserHandle.getUserId(entry.info.uid) != mCurrentUser;
131195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
131295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
131395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
1314186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau    /**
1315186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau     * Displays a combined list with "downloaded" and "visible in launcher" apps only.
1316186f29b6d8f00dfc16288b4972d43e874a805229Bernard Chau     */
131795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final AppFilter FILTER_DOWNLOADED_AND_LAUNCHER = new AppFilter() {
131895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
131995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
132095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
132195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
132295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry entry) {
132395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if ((entry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
132495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return true;
132595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } else if ((entry.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
132695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return true;
132795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } else if (entry.hasLauncherEntry) {
132895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return true;
132995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
133095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return false;
133195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
133295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
133395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
133495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final AppFilter FILTER_THIRD_PARTY = new AppFilter() {
133595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
133695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
133795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
133895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
133995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry entry) {
134095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            if ((entry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
134195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return true;
134295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            } else if ((entry.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
134395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler                return true;
134495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            }
134595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return false;
134695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
134795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
134895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
134995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final AppFilter FILTER_DISABLED = new AppFilter() {
135095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
135195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
135295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
135395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
135495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry entry) {
135595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return !entry.info.enabled;
135695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
135795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
135895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
135995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final AppFilter FILTER_ALL_ENABLED = new AppFilter() {
136095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
136195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
136295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
136395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
136495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry entry) {
136595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return entry.info.enabled;
136695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
136795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
136895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
136995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final AppFilter FILTER_EVERYTHING = new AppFilter() {
137095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
137195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
137295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
137395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
137495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry entry) {
137595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return true;
137695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
137795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
137895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
137995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static final AppFilter FILTER_WITH_DOMAIN_URLS = new AppFilter() {
138095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
138195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
138295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
138395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
138495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry entry) {
138595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return (entry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
138695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
138795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    };
138895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
138995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static class VolumeFilter implements AppFilter {
139095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        private final String mVolumeUuid;
139195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
139295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public VolumeFilter(String volumeUuid) {
139395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mVolumeUuid = volumeUuid;
139495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
139595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
139695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
139795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
139895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
139995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
140095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
140195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry info) {
140295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return Objects.equals(info.info.volumeUuid, mVolumeUuid);
140395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
140495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
140595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
140695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    public static class CompoundFilter implements AppFilter {
140795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        private final AppFilter mFirstFilter;
140895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        private final AppFilter mSecondFilter;
140995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
141095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public CompoundFilter(AppFilter first, AppFilter second) {
141195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mFirstFilter = first;
141295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mSecondFilter = second;
141395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
141495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
141595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
141695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public void init() {
141795357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mFirstFilter.init();
141895357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            mSecondFilter.init();
141995357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
142095357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler
142195357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        @Override
142295357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        public boolean filterApp(AppEntry info) {
142395357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler            return mFirstFilter.filterApp(info) && mSecondFilter.filterApp(info);
142495357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler        }
142595357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler    }
142695357fd49a0ffce4c0b653753c013cf951ebac21Tony Mantler}
1427