ManageApplications.java revision 355b32faa924a0b39067dd759ba03e5af97065ca
1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/*
2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License.
6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at
7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and
14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License.
15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
17afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpackage com.android.settings;
18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
19afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.settings.R;
20afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.ActivityManager;
21afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.AlertDialog;
22afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.Dialog;
23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.ListActivity;
24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.ProgressDialog;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.BroadcastReceiver;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Context;
27afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.DialogInterface;
28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
29afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.IntentFilter;
30d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapuimport android.content.SharedPreferences;
31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.pm.ApplicationInfo;
32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.pm.IPackageStatsObserver;
33afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.pm.PackageManager;
34afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.pm.PackageStats;
35afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException;
36afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.res.Configuration;
37afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.res.Resources;
38afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.graphics.drawable.Drawable;
39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.net.Uri;
40afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle;
41afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Handler;
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Message;
43ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapuimport android.os.SystemClock;
44afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.text.format.Formatter;
45afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.Config;
46afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.Log;
47afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.LayoutInflater;
48afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.Menu;
49afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.MenuItem;
50afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.View;
51afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.ViewGroup;
52afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.Window;
53afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.AdapterView;
54afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.BaseAdapter;
55c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapuimport android.widget.Filter;
56c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapuimport android.widget.Filterable;
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.ImageView;
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.ListView;
59afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.TextView;
60afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.AdapterView.OnItemClickListener;
61b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
62b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapuimport java.io.File;
63b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapuimport java.io.FileInputStream;
64b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapuimport java.io.FileNotFoundException;
65b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapuimport java.io.FileOutputStream;
66b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapuimport java.io.IOException;
67b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapuimport java.text.Collator;
68afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.ArrayList;
69afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.Collections;
70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.Comparator;
71afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.HashMap;
72e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Projectimport java.util.HashSet;
73afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.List;
74afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.Map;
75afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.Set;
76afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.TreeMap;
77ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapuimport java.util.concurrent.CountDownLatch;
78afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
79afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
80afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Activity to pick an application that will be used to display installation information and
81afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * options to uninstall/delete user data for system applications. This activity
82afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * can be launched through Settings or via the ACTION_MANAGE_PACKAGE_STORAGE
83afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * intent.
84afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  Initially a compute in progress message is displayed while the application retrieves
85afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  the list of application information from the PackageManager. The size information
86afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  for each package is refreshed to the screen. The resource(app description and
87afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  icon) information for each package is not available yet, so some default values for size
88afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  icon and descriptions are used initially. Later the resource information for each
89afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  application is retrieved and dynamically updated on the screen.
90afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  A Broadcast receiver registers for package additions or deletions when the activity is
91afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  in focus. If the user installs or deletes packages when the activity has focus, the receiver
92afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  gets notified and proceeds to add/delete these packages from the list on the screen.
93afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  This is an unlikely scenario but could happen. The entire list gets created every time
94afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  the activity's onStart gets invoked. This is to avoid having the receiver for the entire
95afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  life cycle of the application.
96afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  The applications can be sorted either alphabetically or
97afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  based on size(descending). If this activity gets launched under low memory
98afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  situations(A low memory notification dispatches intent
99afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  ACTION_MANAGE_PACKAGE_STORAGE) the list is sorted per size.
100afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  If the user selects an application, extended info(like size, uninstall/clear data options,
101afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *  permissions info etc.,) is displayed via the InstalledAppDetails activity.
102afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
103afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpublic class ManageApplications extends ListActivity implements
104afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        OnItemClickListener, DialogInterface.OnCancelListener,
105afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        DialogInterface.OnClickListener {
106afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // TAG for this activity
107afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String TAG = "ManageApplications";
108d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu    private static final String PREFS_NAME = "ManageAppsInfo.prefs";
109d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu    private static final String PREF_DISABLE_CACHE = "disableCache";
110afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
111afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Log information boolean
112afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean localLOGV = Config.LOGV || false;
113ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu    private static final boolean DEBUG_SIZE = false;
114ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu    private static final boolean DEBUG_TIME = false;
115afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
116afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // attributes used as keys when passing values to InstalledAppDetails activity
117afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public static final String APP_PKG_PREFIX = "com.android.settings.";
118afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public static final String APP_PKG_NAME = APP_PKG_PREFIX+"ApplicationPkgName";
119afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public static final String APP_CHG = APP_PKG_PREFIX+"changed";
120afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
121afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // attribute name used in receiver for tagging names of added/deleted packages
122b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final String ATTR_PKG_NAME="p";
123b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final String ATTR_PKGS="ps";
124b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final String ATTR_STATS="ss";
125b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final String ATTR_SIZE_STRS="fs";
126b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
127b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final String ATTR_GET_SIZE_STATUS="passed";
128b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final String ATTR_PKG_STATS="s";
129b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final String ATTR_PKG_SIZE_STR="f";
130afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
131afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // constant value that can be used to check return code from sub activity.
132afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int INSTALLED_APP_DETAILS = 1;
133afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
134afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // sort order that can be changed through the menu can be sorted alphabetically
135afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // or size(descending)
136afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int MENU_OPTIONS_BASE = 0;
137afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public static final int SORT_ORDER_ALPHA = MENU_OPTIONS_BASE + 0;
138afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public static final int SORT_ORDER_SIZE = MENU_OPTIONS_BASE + 1;
139afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Filter options used for displayed list of applications
140afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public static final int FILTER_APPS_ALL = MENU_OPTIONS_BASE + 2;
141afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public static final int FILTER_APPS_THIRD_PARTY = MENU_OPTIONS_BASE + 3;
142afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public static final int FILTER_APPS_RUNNING = MENU_OPTIONS_BASE + 4;
143afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public static final int FILTER_OPTIONS = MENU_OPTIONS_BASE + 5;
144afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Alert Dialog presented to user to find out the filter option
145afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    AlertDialog mAlertDlg;
146afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // sort order
147afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private int mSortOrder = SORT_ORDER_ALPHA;
148afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Filter value
149afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    int mFilterApps = FILTER_APPS_ALL;
150afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
151afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Custom Adapter used for managing items in the list
152afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private AppInfoAdapter mAppInfoAdapter;
153afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
154afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // messages posted to the handler
155afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int HANDLER_MESSAGE_BASE = 0;
156afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int INIT_PKG_INFO = HANDLER_MESSAGE_BASE+1;
157b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final int COMPUTE_BULK_SIZE = HANDLER_MESSAGE_BASE+2;
158afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int REMOVE_PKG = HANDLER_MESSAGE_BASE+3;
159afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int REORDER_LIST = HANDLER_MESSAGE_BASE+4;
160afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int ADD_PKG_START = HANDLER_MESSAGE_BASE+5;
161afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int ADD_PKG_DONE = HANDLER_MESSAGE_BASE+6;
162b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final int REFRESH_LABELS = HANDLER_MESSAGE_BASE+7;
163e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    private static final int REFRESH_DONE = HANDLER_MESSAGE_BASE+8;
164e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    private static final int NEXT_LOAD_STEP = HANDLER_MESSAGE_BASE+9;
165ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu    private static final int COMPUTE_END = HANDLER_MESSAGE_BASE+10;
166b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private static final int REFRESH_ICONS = HANDLER_MESSAGE_BASE+11;
167afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
168afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // observer object used for computing pkg sizes
169afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private PkgSizeObserver mObserver;
170afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // local handle to PackageManager
171afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private PackageManager mPm;
172afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Broadcast Receiver object that receives notifications for added/deleted
173afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // packages
174afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private PackageIntentReceiver mReceiver;
175afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // atomic variable used to track if computing pkg sizes is in progress. should be volatile?
176afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
177afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mComputeSizes = false;
178afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // default icon thats used when displaying applications initially before resource info is
179afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // retrieved
180355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu    private static Drawable mDefaultAppIcon;
181afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
182afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // temporary dialog displayed while the application info loads
183afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int DLG_BASE = 0;
184afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int DLG_LOADING = DLG_BASE + 1;
185afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
186afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Size resource used for packages whose size computation failed for some reason
187afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private CharSequence mInvalidSizeStr;
188afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private CharSequence mComputingSizeStr;
189afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
190afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // map used to store list of added and removed packages. Immutable Boolean
191afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // variables indicate if a package has been added or removed. If a package is
192afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // added or deleted multiple times a single entry with the latest operation will
193afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // be recorded in the map.
194afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private Map<String, Boolean> mAddRemoveMap;
195afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
196afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // layout inflater object used to inflate views
197afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private LayoutInflater mInflater;
198afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
199afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // invalid size value used initially and also when size retrieval through PackageManager
200afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // fails for whatever reason
201afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int SIZE_INVALID = -1;
202afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
203afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // debug boolean variable to test delays from PackageManager API's
204afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean DEBUG_PKG_DELAY = false;
205afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
206afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Thread to load resources
207afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    ResourceLoaderThread mResourceThread;
208ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu    private TaskRunner mSizeComputor;
209afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
210afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    String mCurrentPkgName;
211afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
212b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    // Cache application attributes
213b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private AppInfoCache mCache = new AppInfoCache();
214afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
215afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // empty message displayed when list is empty
216afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private TextView mEmptyView;
217afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
218afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Boolean variables indicating state
219afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mLoadLabels = false;
220afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mSizesFirst = false;
221afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // ListView used to display list
222afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private ListView mListView;
223afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // State variables used to figure out menu options and also
224afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // initiate the first computation and loading of resources
225afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mJustCreated = true;
226afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mFirst = false;
227ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu    private long mLoadTimeStart;
228b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private boolean mSetListViewLater = true;
229afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
230afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /*
231afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Handler class to handle messages for various operations
232afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Most of the operations that effect Application related data
233afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * are posted as messages to the handler to avoid synchronization
234afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * when accessing these structures.
235afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * When the size retrieval gets kicked off for the first time, a COMPUTE_PKG_SIZE_START
236afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * message is posted to the handler which invokes the getSizeInfo for the pkg at index 0
237afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * When the PackageManager's asynchronous call back through
238afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * PkgSizeObserver.onGetStatsCompleted gets invoked, the application resources like
239afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * label, description, icon etc., is loaded in the same thread and these values are
240afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * set on the observer. The observer then posts a COMPUTE_PKG_SIZE_DONE message
241afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * to the handler. This information is updated on the AppInfoAdapter associated with
242afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * the list view of this activity and size info retrieval is initiated for the next package as
243afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * indicated by mComputeIndex
244afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * When a package gets added while the activity has focus, the PkgSizeObserver posts
245afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * ADD_PKG_START message to the handler.  If the computation is not in progress, the size
246afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * is retrieved for the newly added package through the observer object and the newly
247afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * installed app info is updated on the screen. If the computation is still in progress
248afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * the package is added to an internal structure and action deferred till the computation
249afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * is done for all the packages.
250afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * When a package gets deleted, REMOVE_PKG is posted to the handler
251afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *  if computation is not in progress(as indicated by
252afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * mDoneIniting), the package is deleted from the displayed list of apps. If computation is
253afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * still in progress the package is added to an internal structure and action deferred till
254afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * the computation is done for all packages.
255afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * When the sizes of all packages is computed, the newly
256afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * added or removed packages are processed in order.
257afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * If the user changes the order in  which these applications are viewed by hitting the
258afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * menu key, REORDER_LIST message is posted to the handler. this sorts the list
259afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * of items based on the sort order.
260afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
261afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private Handler mHandler = new Handler() {
262afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public void handleMessage(Message msg) {
263b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            boolean status;
264b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            long size;
265b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            String formattedSize;
266afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            ApplicationInfo info;
267afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            Bundle data;
268afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            String pkgName = null;
269afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            AppInfo appInfo;
270afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            data = msg.getData();
271afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if(data != null) {
272afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                pkgName = data.getString(ATTR_PKG_NAME);
273afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
274afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            switch (msg.what) {
275afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case INIT_PKG_INFO:
276b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if(localLOGV) Log.i(TAG, "Message INIT_PKG_INFO, justCreated = " + mJustCreated);
277b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                List<ApplicationInfo> newList = null;
27872ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                if (!mJustCreated) {
279355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                    if (localLOGV) Log.i(TAG, "List already created");
28072ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                    // Add or delete newly created packages by comparing lists
281b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    newList = getInstalledApps(FILTER_APPS_ALL);
282e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    updateAppList(newList);
28372ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                }
284afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // Retrieve the package list and init some structures
285b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                initAppList(newList, mFilterApps);
286afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
287afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
288b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            case COMPUTE_BULK_SIZE:
289b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if(localLOGV) Log.i(TAG, "Message COMPUTE_BULK_PKG_SIZE");
290b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                String[] pkgs = data.getStringArray(ATTR_PKGS);
291b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                long[] sizes = data.getLongArray(ATTR_STATS);
292b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                String[] formatted = data.getStringArray(ATTR_SIZE_STRS);
293b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if(pkgs == null || sizes == null || formatted == null) {
294afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                     Log.w(TAG, "Ignoring message");
295afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                     break;
296afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
297b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                mAppInfoAdapter.bulkUpdateSizes(pkgs, sizes, formatted);
298ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                break;
299ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            case COMPUTE_END :
300ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                mComputeSizes = true;
301ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                mFirst = true;
302ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
303afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
304afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case REMOVE_PKG:
305afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if(localLOGV) Log.i(TAG, "Message REMOVE_PKG");
306afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if(pkgName == null) {
307afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    Log.w(TAG, "Ignoring message:REMOVE_PKG for null pkgName");
308afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    break;
309afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
310afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (!mComputeSizes) {
311afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    Boolean currB = mAddRemoveMap.get(pkgName);
312afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if (currB == null || (currB.equals(Boolean.TRUE))) {
313afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        mAddRemoveMap.put(pkgName, Boolean.FALSE);
314afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
315afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    break;
316afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
317afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                List<String> pkgList = new ArrayList<String>();
318afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                pkgList.add(pkgName);
319afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mAppInfoAdapter.removeFromList(pkgList);
320afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
321afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case REORDER_LIST:
322afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if(localLOGV) Log.i(TAG, "Message REORDER_LIST");
323afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                int menuOption = msg.arg1;
324afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if((menuOption == SORT_ORDER_ALPHA) ||
325afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        (menuOption == SORT_ORDER_SIZE)) {
326afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    // Option to sort list
327afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if (menuOption != mSortOrder) {
328afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        mSortOrder = menuOption;
329afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        if (localLOGV) Log.i(TAG, "Changing sort order to "+mSortOrder);
330afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        mAppInfoAdapter.sortList(mSortOrder);
331afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
332afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                } else if(menuOption != mFilterApps) {
333afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    // Option to filter list
334afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    mFilterApps = menuOption;
335e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    boolean ret = mAppInfoAdapter.resetAppList(mFilterApps);
336afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if(!ret) {
337afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        // Reset cache
338afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        mFilterApps = FILTER_APPS_ALL;
339afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        mHandler.sendEmptyMessage(INIT_PKG_INFO);
340afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        sendMessageToHandler(REORDER_LIST, menuOption);
341afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
342afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
343afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
344afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case ADD_PKG_START:
345afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if(localLOGV) Log.i(TAG, "Message ADD_PKG_START");
346afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if(pkgName == null) {
347afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    Log.w(TAG, "Ignoring message:ADD_PKG_START for null pkgName");
348afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    break;
349afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
350e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                if (!mComputeSizes || !mLoadLabels) {
351afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    Boolean currB = mAddRemoveMap.get(pkgName);
352afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if (currB == null || (currB.equals(Boolean.FALSE))) {
353afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        mAddRemoveMap.put(pkgName, Boolean.TRUE);
354afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
355afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    break;
356afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
357afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                try {
358e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    info = mPm.getApplicationInfo(pkgName, 0);
359e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                } catch (NameNotFoundException e) {
360e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    Log.w(TAG, "Couldnt find application info for:"+pkgName);
361e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    break;
362e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                }
363489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                mObserver.invokeGetSizeInfo(pkgName);
364afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
365afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case ADD_PKG_DONE:
366b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if(localLOGV) Log.i(TAG, "Message ADD_PKG_DONE");
367afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if(pkgName == null) {
368afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    Log.w(TAG, "Ignoring message:ADD_PKG_START for null pkgName");
369afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    break;
370afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
371b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                status = data.getBoolean(ATTR_GET_SIZE_STATUS);
372b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (status) {
373b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    size = data.getLong(ATTR_PKG_STATS);
374b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    formattedSize = data.getString(ATTR_PKG_SIZE_STR);
375355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                    if (!mAppInfoAdapter.isInstalled(pkgName)) {
376489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                        mAppInfoAdapter.addToList(pkgName, size, formattedSize);
377489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                    } else {
378489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                        mAppInfoAdapter.updatePackage(pkgName, size, formattedSize);
379489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                    }
380b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
381afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
382b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            case REFRESH_LABELS:
383b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Map<String, CharSequence> labelMap = (Map<String, CharSequence>) msg.obj;
384b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (labelMap != null) {
385b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    mAppInfoAdapter.bulkUpdateLabels(labelMap);
386b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
387b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                break;
388b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            case REFRESH_ICONS:
389b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Map<String, Drawable> iconMap = (Map<String, Drawable>) msg.obj;
390b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (iconMap != null) {
391b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    mAppInfoAdapter.bulkUpdateIcons(iconMap);
392afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
393e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                break;
394e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            case REFRESH_DONE:
395afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLoadLabels = true;
396afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
397afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
398afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case NEXT_LOAD_STEP:
399b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (!mCache.isEmpty() && mSetListViewLater) {
400b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if (localLOGV) Log.i(TAG, "Using cache to populate list view");
401b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    initListView();
402b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    mSetListViewLater = false;
403b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    mFirst = true;
404b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
405afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (mComputeSizes && mLoadLabels) {
406afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    doneLoadingData();
407e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    // Check for added/removed packages
408e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    Set<String> keys =  mAddRemoveMap.keySet();
409e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    for (String key : keys) {
410e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                        if (mAddRemoveMap.get(key) == Boolean.TRUE) {
411e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                            // Add the package
412e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                            updatePackageList(Intent.ACTION_PACKAGE_ADDED, key);
413e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                        } else {
414e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                            // Remove the package
415e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                            updatePackageList(Intent.ACTION_PACKAGE_REMOVED, key);
416e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                        }
417e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    }
418e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    mAddRemoveMap.clear();
419afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                } else if (!mComputeSizes && !mLoadLabels) {
420afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                     // Either load the package labels or initiate get size info
421afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if (mSizesFirst) {
422afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        initComputeSizes();
423afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    } else {
424afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        initResourceThread();
425afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
426afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                } else {
427b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if (mSetListViewLater) {
428b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        if (localLOGV) Log.i(TAG, "Initing list view for very first time");
429b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        initListView();
430b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        mSetListViewLater = false;
431b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
432afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if (!mComputeSizes) {
433afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        initComputeSizes();
434afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    } else if (!mLoadLabels) {
435afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        initResourceThread();
436afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
437afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
438afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
439afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            default:
440afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
441afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
442afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
443afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    };
444afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
445b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private void initListView() {
446b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu       // Create list view from the adapter here. Wait till the sort order
447b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        // of list is defined. its either by label or by size. So atleast one of the
448b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        // first steps should have been completed before the list gets filled.
449b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        mAppInfoAdapter.sortBaseList(mSortOrder);
450b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        if (mJustCreated) {
451b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            // Set the adapter here.
452b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            mJustCreated = false;
453b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            mListView.setAdapter(mAppInfoAdapter);
454b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            dismissLoadingMsg();
455b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
456b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    }
457b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
458ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu   class SizeObserver extends IPackageStatsObserver.Stub {
459ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu       private CountDownLatch mCount;
460b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu       PackageStats stats;
461b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu       boolean succeeded;
462ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu
463ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu       public void invokeGetSize(String packageName, CountDownLatch count) {
464ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu           mCount = count;
465ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu           mPm.getPackageSizeInfo(packageName, this);
466ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu       }
467ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu
468ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        public void onGetStatsCompleted(PackageStats pStats, boolean pSucceeded) {
469b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            succeeded = pSucceeded;
470b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            stats = pStats;
471ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            mCount.countDown();
472ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        }
473ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu    }
474ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu
475ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu    class TaskRunner extends Thread {
476ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        private List<ApplicationInfo> mPkgList;
477ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        private SizeObserver mSizeObserver;
478ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        private static final int END_MSG = COMPUTE_END;
479b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private static final int SEND_PKG_SIZES = COMPUTE_BULK_SIZE;
480ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        volatile boolean abort = false;
481b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        static final int MSG_PKG_SIZE = 8;
482ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu
483ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        TaskRunner(List<ApplicationInfo> appList) {
484ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu           mPkgList = appList;
485b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu           mSizeObserver = new SizeObserver();
486ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu           start();
487ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        }
488ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu
489ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        public void setAbort() {
490ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            abort = true;
491ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        }
492ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu
493ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        public void run() {
494ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            long startTime;
495ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            if (DEBUG_SIZE || DEBUG_TIME) {
496ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu               startTime =  SystemClock.elapsedRealtime();
497ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            }
498ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            int size = mPkgList.size();
499b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            int numMsgs = size / MSG_PKG_SIZE;
500b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (size > (numMsgs * MSG_PKG_SIZE)) {
501b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                numMsgs++;
502b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
503b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            int endi = 0;
504b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            for (int j = 0; j < size; j += MSG_PKG_SIZE) {
505b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                long sizes[];
506b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                String formatted[];
507b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                String packages[];
508b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                endi += MSG_PKG_SIZE;
509b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (endi > size) {
510b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    endi = size;
511ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                }
512b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                sizes = new long[endi-j];
513b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                formatted = new String[endi-j];
514b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                packages = new String[endi-j];
515b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                for (int i = j; i < endi; i++) {
516b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if (abort) {
517b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        // Exit if abort has been set.
518b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        break;
519b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
520b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    CountDownLatch count = new CountDownLatch(1);
521b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    String packageName = mPkgList.get(i).packageName;
522b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    mSizeObserver.invokeGetSize(packageName, count);
523b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    try {
524b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        count.await();
525b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    } catch (InterruptedException e) {
526b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        Log.i(TAG, "Failed computing size for pkg : "+packageName);
527b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
528b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    // Process the package statistics
529b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    PackageStats pStats = mSizeObserver.stats;
530b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    boolean succeeded = mSizeObserver.succeeded;
531b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    long total;
532b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if(succeeded && pStats != null) {
533b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        total = getTotalSize(pStats);
534b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    } else {
535b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        total = SIZE_INVALID;
536b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
537b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    sizes[i-j] = total;
538b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    formatted[i-j] = getSizeStr(total).toString();
539b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    packages[i-j] = packageName;
540ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                }
541b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                // Post update message
542b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Bundle data = new Bundle();
543b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                data.putStringArray(ATTR_PKGS, packages);
544b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                data.putLongArray(ATTR_STATS, sizes);
545b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                data.putStringArray(ATTR_SIZE_STRS, formatted);
546b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Message msg = mHandler.obtainMessage(SEND_PKG_SIZES, data);
547b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                msg.setData(data);
548b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                mHandler.sendMessage(msg);
549ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            }
550b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (DEBUG_SIZE || DEBUG_TIME) Log.i(TAG, "Took "+
551b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    (SystemClock.elapsedRealtime() - startTime)+
552b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    " ms to compute sizes of all packages ");
553ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            mHandler.sendEmptyMessage(END_MSG);
554ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        }
555ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu    }
556ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu
557e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    /*
558e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     * This method compares the current cache against a new list of
559e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     * installed applications and tries to update the list with add or remove
560e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     * messages.
561e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     */
562e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    private boolean updateAppList(List<ApplicationInfo> newList) {
563b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        if ((newList == null) || mCache.isEmpty()) {
564e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            return false;
565e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
566e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        Set<String> existingList = new HashSet<String>();
567e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        boolean ret = false;
568e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        // Loop over new list and find out common elements between old and new lists
569355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu        int N = newList.size();
570355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu        for (int i = (N-1); i >= 0; i--) {
571355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            ApplicationInfo info = newList.get(i);
572e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            String pkgName = info.packageName;
573b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            AppInfo aInfo = mCache.getEntry(pkgName);
574e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            if (aInfo != null) {
575e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                existingList.add(pkgName);
576e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            } else {
577e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                // New package. update info by refreshing
578e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                if (localLOGV) Log.i(TAG, "New pkg :"+pkgName+" installed when paused");
579e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                updatePackageList(Intent.ACTION_PACKAGE_ADDED, pkgName);
580355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                // Remove from current list so that the newly added package can
581355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                // be handled later
582355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                newList.remove(i);
583e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                ret = true;
584e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            }
585e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
586355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu
587355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu        // Loop over old list and figure out stale entries
588e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        List<String> deletedList = null;
589b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        Set<String> staleList = mCache.getPkgList();
590e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        for (String pkgName : staleList) {
591e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            if (!existingList.contains(pkgName)) {
592e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                if (localLOGV) Log.i(TAG, "Pkg :"+pkgName+" deleted when paused");
593e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                if (deletedList == null) {
594e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    deletedList = new ArrayList<String>();
595e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    deletedList.add(pkgName);
596e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                }
597e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                ret = true;
598e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            }
599e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
600e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        // Delete right away
601e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        if (deletedList != null) {
602355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            if (localLOGV) Log.i(TAG, "Deleting right away");
603e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            mAppInfoAdapter.removeFromList(deletedList);
604e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
605e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        return ret;
606e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    }
607afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
608afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void doneLoadingData() {
609afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        setProgressBarIndeterminateVisibility(false);
610afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
611afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
612afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    List<ApplicationInfo> getInstalledApps(int filterOption) {
613afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        List<ApplicationInfo> installedAppList = mPm.getInstalledApplications(
614afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                PackageManager.GET_UNINSTALLED_PACKAGES);
615afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (installedAppList == null) {
616afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return new ArrayList<ApplicationInfo> ();
617afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
618afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (filterOption == FILTER_APPS_THIRD_PARTY) {
619afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            List<ApplicationInfo> appList =new ArrayList<ApplicationInfo> ();
620afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            for (ApplicationInfo appInfo : installedAppList) {
621afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                boolean flag = false;
622afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if ((appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
623afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    // Updated system app
624afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    flag = true;
625afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                } else if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
626afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    // Non-system app
627afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    flag = true;
628afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
629afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (flag) {
630afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    appList.add(appInfo);
631afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
632afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
633afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return appList;
634afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (filterOption == FILTER_APPS_RUNNING) {
635afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            List<ApplicationInfo> appList =new ArrayList<ApplicationInfo> ();
636afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            List<ActivityManager.RunningAppProcessInfo> procList = getRunningAppProcessesList();
637afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if ((procList == null) || (procList.size() == 0)) {
638afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return appList;
639afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
640afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Retrieve running processes from ActivityManager
641afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            for (ActivityManager.RunningAppProcessInfo appProcInfo : procList) {
642afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if ((appProcInfo != null)  && (appProcInfo.pkgList != null)){
643afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    int size = appProcInfo.pkgList.length;
644afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    for (int i = 0; i < size; i++) {
645afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        ApplicationInfo appInfo = null;
646afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        try {
647afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                            appInfo = mPm.getApplicationInfo(appProcInfo.pkgList[i],
648afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                                    PackageManager.GET_UNINSTALLED_PACKAGES);
649afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        } catch (NameNotFoundException e) {
650afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                           Log.w(TAG, "Error retrieving ApplicationInfo for pkg:"+appProcInfo.pkgList[i]);
651afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                           continue;
652afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        }
653afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        if(appInfo != null) {
654afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                            appList.add(appInfo);
655afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        }
656afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
657afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
658afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
659afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return appList;
660afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
661afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return installedAppList;
662afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
663afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
664c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu
665c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu    private static boolean matchFilter(boolean filter, Map<String, String> filterMap, String pkg) {
666c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        boolean add = true;
667c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        if (filter) {
668c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            if (filterMap == null || !filterMap.containsKey(pkg)) {
669c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                add = false;
670c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            }
671c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        }
672c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        return add;
673c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu    }
674afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
675e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    /*
676e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     * Utility method used to figure out list of apps based on filterOption
677e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     * If the framework supports an additional flag to indicate running apps
678e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     *  we can get away with some code here.
679e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     */
680c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu    List<ApplicationInfo> getFilteredApps(List<ApplicationInfo> pAppList, int filterOption, boolean filter,
681c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            Map<String, String> filterMap) {
682e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
683e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        if(pAppList == null) {
684e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            return retList;
685e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
686e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        if (filterOption == FILTER_APPS_THIRD_PARTY) {
687e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            for (ApplicationInfo appInfo : pAppList) {
688e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                boolean flag = false;
689e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                if ((appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
690e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    // Updated system app
691e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    flag = true;
692e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                } else if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
693e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    // Non-system app
694e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    flag = true;
695e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                }
696e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                if (flag) {
697c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    if (matchFilter(filter, filterMap, appInfo.packageName)) {
698c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        retList.add(appInfo);
699c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    }
700e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                }
701e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            }
702c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            return retList;
703e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        } else if (filterOption == FILTER_APPS_RUNNING) {
704e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            List<ActivityManager.RunningAppProcessInfo> procList = getRunningAppProcessesList();
705e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            if ((procList == null) || (procList.size() == 0)) {
706c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                return retList;
707e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            }
708e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            // Retrieve running processes from ActivityManager
709e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            HashMap<String, ActivityManager.RunningAppProcessInfo> runningMap =
710e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                new HashMap<String, ActivityManager.RunningAppProcessInfo>();
711e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            for (ActivityManager.RunningAppProcessInfo appProcInfo : procList) {
712e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                if ((appProcInfo != null)  && (appProcInfo.pkgList != null)){
713e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    int size = appProcInfo.pkgList.length;
714e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    for (int i = 0; i < size; i++) {
715e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                        runningMap.put(appProcInfo.pkgList[i], appProcInfo);
716e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    }
717e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                }
718e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            }
719e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            // Query list to find running processes in current list
720e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            for (ApplicationInfo appInfo : pAppList) {
721e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                if (runningMap.get(appInfo.packageName) != null) {
722c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    if (matchFilter(filter, filterMap, appInfo.packageName)) {
723c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        retList.add(appInfo);
724c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    }
725e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                }
726e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            }
727c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            return retList;
728e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        } else {
729c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            for (ApplicationInfo appInfo : pAppList) {
730c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                if (matchFilter(filter, filterMap, appInfo.packageName)) {
731c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    retList.add(appInfo);
732c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                }
733c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            }
734c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            return retList;
735e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
736e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    }
737c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu
738afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesList() {
739afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
740afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return am.getRunningAppProcesses();
741afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
742b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
743b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu     // Some initialization code used when kicking off the size computation
74472ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project    private void initAppList(List<ApplicationInfo> appList, int filterOption) {
745afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        setProgressBarIndeterminateVisibility(true);
746afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mComputeSizes = false;
747afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mLoadLabels = false;
748afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Initialize lists
749afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mAddRemoveMap = new TreeMap<String, Boolean>();
750e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        mAppInfoAdapter.initMapFromList(appList, filterOption);
751afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
752b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
753afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Utility method to start a thread to read application labels and icons
754afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void initResourceThread() {
755ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        if ((mResourceThread != null) && mResourceThread.isAlive()) {
756ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            mResourceThread.setAbort();
757ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        }
758ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        mResourceThread = new ResourceLoaderThread();
759ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        List<ApplicationInfo> appList = mAppInfoAdapter.getBaseAppList();
760ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        if ((appList != null) && (appList.size()) > 0) {
761ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            mResourceThread.loadAllResources(appList);
762afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
763afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
764b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
765afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void initComputeSizes() {
766ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu         // Initiate compute package sizes
767afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (localLOGV) Log.i(TAG, "Initiating compute sizes for first time");
768ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        if ((mSizeComputor != null) && (mSizeComputor.isAlive())) {
769ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            mSizeComputor.setAbort();
770ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        }
771ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        List<ApplicationInfo> appList = mAppInfoAdapter.getBaseAppList();
772ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        if ((appList != null) && (appList.size()) > 0) {
773ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            mSizeComputor = new TaskRunner(appList);
774afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
775afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mComputeSizes = true;
776afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
777afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
778afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
779afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void showEmptyViewIfListEmpty() {
780afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (localLOGV) Log.i(TAG, "Checking for empty view");
781afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mAppInfoAdapter.getCount() > 0) {
782afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mListView.setVisibility(View.VISIBLE);
783afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mEmptyView.setVisibility(View.GONE);
784afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
785afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mListView.setVisibility(View.GONE);
786afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mEmptyView.setVisibility(View.VISIBLE);
787afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
788afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
789afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
790afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // internal structure used to track added and deleted packages when
791afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // the activity has focus
7928762093e0094e09493fa6cbac8e8fbf265f18165Michael Chan    static class AddRemoveInfo {
793afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        String pkgName;
794afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        boolean add;
795afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public AddRemoveInfo(String pPkgName, boolean pAdd) {
796afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pkgName = pPkgName;
797afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            add = pAdd;
798afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
799afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
800afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
801afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    class ResourceLoaderThread extends Thread {
802afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        List<ApplicationInfo> mAppList;
803ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        volatile boolean abort = false;
804b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        static final int MSG_PKG_SIZE = 8;
805afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
806ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        public void setAbort() {
807ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            abort = true;
808ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        }
809afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        void loadAllResources(List<ApplicationInfo> appList) {
810afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mAppList = appList;
811afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            start();
812afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
813afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
814afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public void run() {
815ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            long start;
816ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            if (DEBUG_TIME) {
817ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                start = SystemClock.elapsedRealtime();
818ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            }
819ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            int imax;
820ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            if(mAppList == null || (imax = mAppList.size()) <= 0) {
821afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.w(TAG, "Empty or null application list");
822afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else {
823b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                int size = mAppList.size();
824b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                int numMsgs = size / MSG_PKG_SIZE;
825b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (size > (numMsgs * MSG_PKG_SIZE)) {
826b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    numMsgs++;
827b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
828b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                int endi = 0;
829b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                for (int j = 0; j < size; j += MSG_PKG_SIZE) {
830b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    Map<String, CharSequence> map = new HashMap<String, CharSequence>();
831b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    endi += MSG_PKG_SIZE;
832b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if (endi > size) {
833b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        endi = size;
834ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                    }
835b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    for (int i = j; i < endi; i++) {
836b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        if (abort) {
837b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                            // Exit if abort has been set.
838b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                            break;
839b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        }
840b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        ApplicationInfo appInfo = mAppList.get(i);
841b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        map.put(appInfo.packageName, appInfo.loadLabel(mPm));
842b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
843b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    // Post update message
844b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    Message msg = mHandler.obtainMessage(REFRESH_LABELS);
845b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    msg.obj = map;
846ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                    mHandler.sendMessage(msg);
847ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                }
848ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                Message doneMsg = mHandler.obtainMessage(REFRESH_DONE);
849ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                mHandler.sendMessage(doneMsg);
850b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (DEBUG_TIME) Log.i(TAG, "Took "+(SystemClock.elapsedRealtime()-start)+
851b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        " ms to load app labels");
852ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                long startIcons;
853ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                if (DEBUG_TIME) {
854ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                    startIcons = SystemClock.elapsedRealtime();
855ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                }
856b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Map<String, Drawable> map = new HashMap<String, Drawable>();
857ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                for (int i = (imax-1); i >= 0; i--) {
858ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                    if (abort) {
859ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                        return;
860ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                    }
861ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                    ApplicationInfo appInfo = mAppList.get(i);
862b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    map.put(appInfo.packageName, appInfo.loadIcon(mPm));
863afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
864b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Message msg = mHandler.obtainMessage(REFRESH_ICONS);
865b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                msg.obj = map;
866b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                mHandler.sendMessage(msg);
867ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                if (DEBUG_TIME) Log.i(TAG, "Took "+(SystemClock.elapsedRealtime()-startIcons)+" ms to load app icons");
868afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
869ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            if (DEBUG_TIME) Log.i(TAG, "Took "+(SystemClock.elapsedRealtime()-start)+" ms to load app resources");
870afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
871afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
872afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
873afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /* Internal class representing an application or packages displayable attributes
874afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
875afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
876355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu    static private class AppInfo {
877afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public String pkgName;
878afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int index;
879afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public  CharSequence appName;
880afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public  Drawable appIcon;
881afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public CharSequence appSize;
882b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        long size;
883ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu
884b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public void refreshIcon(Drawable icon) {
885b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (icon == null) {
886ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu                return;
887ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            }
888b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            appIcon = icon;
889b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
890b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public void refreshLabel(CharSequence label) {
891b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (label == null) {
892b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                return;
893ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            }
894b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            appName = label;
895afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
896b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
897b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public AppInfo(String pName, int pIndex, CharSequence aName,
898b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                long pSize,
899b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                CharSequence pSizeStr) {
900b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            this(pName, pIndex, aName, mDefaultAppIcon, pSize, pSizeStr);
901afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
902b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
903b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public AppInfo(String pName, int pIndex, CharSequence aName, Drawable aIcon,
904b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                long pSize,
905b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                CharSequence pSizeStr) {
906afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            index = pIndex;
907afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pkgName = pName;
908afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            appName = aName;
909afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            appIcon = aIcon;
910b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            size = pSize;
911b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            appSize = pSizeStr;
912afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
913b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
914b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public boolean setSize(long newSize, String formattedSize) {
915b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (size != newSize) {
916b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                size = newSize;
917b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                appSize = formattedSize;
918b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                return true;
919afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
920b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            return false;
921afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
922b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    }
923b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
924b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private long getTotalSize(PackageStats ps) {
925b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        if (ps != null) {
926b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            return ps.cacheSize+ps.codeSize+ps.dataSize;
927afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
928b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        return SIZE_INVALID;
929b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    }
930b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
931b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    private CharSequence getSizeStr(long size) {
932b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        CharSequence appSize = null;
933b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        if (size == SIZE_INVALID) {
934b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu             return mInvalidSizeStr;
935afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
936b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        appSize = Formatter.formatFileSize(ManageApplications.this, size);
937b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        return appSize;
938afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
939b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
940afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // View Holder used when displaying views
941afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    static class AppViewHolder {
942afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        TextView appName;
943afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ImageView appIcon;
944afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        TextView appSize;
945afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
946afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
947b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    /*
948b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu     * Custom adapter implementation for the ListView
949afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * This adapter maintains a map for each displayed application and its properties
950afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * An index value on each AppInfo object indicates the correct position or index
951afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * in the list. If the list gets updated dynamically when the user is viewing the list of
952afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * applications, we need to return the correct index of position. This is done by mapping
953afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * the getId methods via the package name into the internal maps and indices.
954afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * The order of applications in the list is mirrored in mAppLocalList
955afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
956c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu    class AppInfoAdapter extends BaseAdapter implements Filterable {
957e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        private List<ApplicationInfo> mAppList;
958afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        private List<ApplicationInfo> mAppLocalList;
959c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        private Map<String, String> mFilterMap = new HashMap<String, String>();
960b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        AlphaComparator mAlphaComparator = new AlphaComparator();
961b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        SizeComparator mSizeComparator = new SizeComparator();
962c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        private Filter mAppFilter = new AppFilter();
963c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        final private Object mFilterLock = new Object();
964c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        private Map<String, String> mCurrentFilterMap = null;
965c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu
966c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        private void generateFilterListLocked(List<ApplicationInfo> list) {
967c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            mAppLocalList = new ArrayList<ApplicationInfo>(list);
968c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            synchronized(mFilterLock) {
969c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                for (ApplicationInfo info : mAppLocalList) {
970c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    String label = info.packageName;
971c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    AppInfo aInfo = mCache.getEntry(info.packageName);
972c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    if ((aInfo != null) && (aInfo.appName != null)) {
973c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        label = aInfo.appName.toString();
974c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    }
975c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    mFilterMap.put(info.packageName, label.toLowerCase());
976c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                }
977c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            }
978c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        }
979c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu
980c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        private void addFilterListLocked(int newIdx, ApplicationInfo info, CharSequence pLabel) {
981c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            mAppLocalList.add(newIdx, info);
982c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            synchronized (mFilterLock) {
983c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                String label = info.packageName;
984c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                if (pLabel != null) {
985c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    label = pLabel.toString();
986c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                }
987c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                mFilterMap.put(info.packageName, label.toLowerCase());
988c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            }
989c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        }
990c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu
991c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        private boolean removeFilterListLocked(String removePkg) {
992c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            // Remove from filtered list
993c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            int N = mAppLocalList.size();
994c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            int i;
995c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            for (i = (N-1); i >= 0; i--) {
996c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                ApplicationInfo info = mAppLocalList.get(i);
997c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                if (info.packageName.equalsIgnoreCase(removePkg)) {
998c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    if (localLOGV) Log.i(TAG, "Removing " + removePkg + " from local list");
999c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    mAppLocalList.remove(i);
1000c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    synchronized (mFilterLock) {
1001c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        mFilterMap.remove(removePkg);
1002c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    }
1003c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    return true;
1004c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                }
1005c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            }
1006c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            return false;
1007c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        }
1008c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu
1009c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        private void reverseGenerateList() {
1010c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            generateFilterListLocked(getFilteredApps(mAppList, mFilterApps, mCurrentFilterMap!= null, mCurrentFilterMap));
1011c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            sortListInner(mSortOrder);
1012c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        }
1013e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
1014e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        // Make sure the cache or map contains entries for all elements
1015e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        // in appList for a valid sort.
1016b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public void initMapFromList(List<ApplicationInfo> pAppList, int filterOption) {
1017b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            boolean notify = false;
1018b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            List<ApplicationInfo> appList = null;
1019b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (pAppList == null) {
1020e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                // Just refresh the list
1021e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                appList = mAppList;
1022e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            } else {
1023c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                mAppList = new ArrayList<ApplicationInfo>(pAppList);
1024b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                appList = pAppList;
1025b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                notify = true;
1026afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1027c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            generateFilterListLocked(getFilteredApps(appList, filterOption, mCurrentFilterMap!= null, mCurrentFilterMap));
1028b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            // This loop verifies and creates new entries for new packages in list
1029e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            int imax = appList.size();
1030afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            for (int i = 0; i < imax; i++) {
1031e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                ApplicationInfo info  = appList.get(i);
1032b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                AppInfo aInfo = mCache.getEntry(info.packageName);
1033afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if(aInfo == null){
1034afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    aInfo = new AppInfo(info.packageName, i,
1035b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                            info.packageName, -1, mComputingSizeStr);
1036e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    if (localLOGV) Log.i(TAG, "Creating entry pkg:"+info.packageName+" to map");
1037b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    mCache.addEntry(aInfo);
1038afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
1039b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1040b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            sortListInner(mSortOrder);
1041b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (notify) {
1042b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                notifyDataSetChanged();
1043afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1044afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1045afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1046e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        public AppInfoAdapter(Context c, List<ApplicationInfo> appList) {
1047ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu           mAppList = appList;
1048e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
1049e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
1050afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public int getCount() {
1051afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return mAppLocalList.size();
1052afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1053afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1054afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public Object getItem(int position) {
1055afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return mAppLocalList.get(position);
1056afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1057afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1058355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu        public boolean isInstalled(String pkgName) {
1059afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if(pkgName == null) {
1060355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                if (localLOGV) Log.w(TAG, "Null pkg name when checking if installed");
1061355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                return false;
1062afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1063355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            for (ApplicationInfo info : mAppList) {
1064355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                if (info.packageName.equalsIgnoreCase(pkgName)) {
1065355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                    return true;
1066afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
1067afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1068355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            return false;
1069afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1070355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu
1071afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public ApplicationInfo getApplicationInfo(int position) {
1072afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int imax = mAppLocalList.size();
1073afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if( (position < 0) || (position >= imax)) {
1074afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.w(TAG, "Position out of bounds in List Adapter");
1075afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return null;
1076afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1077afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return mAppLocalList.get(position);
1078afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1079afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1080afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public long getItemId(int position) {
1081afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int imax = mAppLocalList.size();
1082afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if( (position < 0) || (position >= imax)) {
1083afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.w(TAG, "Position out of bounds in List Adapter");
1084afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return -1;
1085afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1086b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            AppInfo aInfo = mCache.getEntry(mAppLocalList.get(position).packageName);
1087b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (aInfo == null) {
1088b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                return -1;
1089b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1090b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            return aInfo.index;
1091afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1092afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1093ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        public List<ApplicationInfo> getBaseAppList() {
1094ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            return mAppList;
1095afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1096afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1097afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public View getView(int position, View convertView, ViewGroup parent) {
1098afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (position >= mAppLocalList.size()) {
1099afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.w(TAG, "Invalid view position:"+position+", actual size is:"+mAppLocalList.size());
1100afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return null;
1101afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1102afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // A ViewHolder keeps references to children views to avoid unneccessary calls
1103afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // to findViewById() on each row.
1104afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            AppViewHolder holder;
1105afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1106afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // When convertView is not null, we can reuse it directly, there is no need
1107afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // to reinflate it. We only inflate a new View when the convertView supplied
1108afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // by ListView is null.
1109afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (convertView == null) {
1110afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                convertView = mInflater.inflate(R.layout.manage_applications_item, null);
1111afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1112afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // Creates a ViewHolder and store references to the two children views
1113afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // we want to bind data to.
1114afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                holder = new AppViewHolder();
1115afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                holder.appName = (TextView) convertView.findViewById(R.id.app_name);
1116afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
1117afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                holder.appSize = (TextView) convertView.findViewById(R.id.app_size);
1118afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                convertView.setTag(holder);
1119afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else {
1120afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // Get the ViewHolder back to get fast access to the TextView
1121afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // and the ImageView.
1122afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                holder = (AppViewHolder) convertView.getTag();
1123afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1124afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1125afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Bind the data efficiently with the holder
1126afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            ApplicationInfo appInfo = mAppLocalList.get(position);
1127b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            AppInfo mInfo = mCache.getEntry(appInfo.packageName);
1128afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if(mInfo != null) {
1129afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if(mInfo.appName != null) {
1130afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    holder.appName.setText(mInfo.appName);
1131afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
1132afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if(mInfo.appIcon != null) {
1133afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    holder.appIcon.setImageDrawable(mInfo.appIcon);
1134afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
1135afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (mInfo.appSize != null) {
1136afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    holder.appSize.setText(mInfo.appSize);
1137afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
1138afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else {
1139afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.w(TAG, "No info for package:"+appInfo.packageName+" in property map");
1140afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1141afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return convertView;
1142afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1143afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1144afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        private void adjustIndex() {
1145afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int imax = mAppLocalList.size();
1146afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            for (int i = 0; i < imax; i++) {
1147e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                ApplicationInfo info = mAppLocalList.get(i);
1148b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                mCache.getEntry(info.packageName).index = i;
1149afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1150afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1151afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1152ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        public void sortAppList(List<ApplicationInfo> appList, int sortOrder) {
1153ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            Collections.sort(appList, getAppComparator(sortOrder));
1154ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        }
1155ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu
1156ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        public void sortBaseList(int sortOrder) {
1157ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            if (localLOGV) Log.i(TAG, "Sorting base list based on sortOrder = "+sortOrder);
1158ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            sortAppList(mAppList, sortOrder);
1159c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            generateFilterListLocked(getFilteredApps(mAppList, mFilterApps, mCurrentFilterMap!= null, mCurrentFilterMap));
1160ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            adjustIndex();
1161afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1162b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1163b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private void sortListInner(int sortOrder) {
1164b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            sortAppList(mAppLocalList, sortOrder);
1165b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            adjustIndex();
1166b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1167afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1168afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public void sortList(int sortOrder) {
1169e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            if (localLOGV) Log.i(TAG, "sortOrder = "+sortOrder);
1170b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            sortListInner(sortOrder);
1171afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            notifyDataSetChanged();
1172afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1173afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1174e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        /*
1175e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project         * Reset the application list associated with this adapter.
1176e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project         * @param filterOption Sort the list based on this value
1177e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project         * @param appList the actual application list that is used to reset
1178e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project         * @return Return a boolean value to indicate inconsistency
1179e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project         */
1180e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        public boolean resetAppList(int filterOption) {
1181e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project           // Change application list based on filter option
1182c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu           generateFilterListLocked(getFilteredApps(mAppList, filterOption, mCurrentFilterMap!= null, mCurrentFilterMap));
1183afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           // Check for all properties in map before sorting. Populate values from cache
1184afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           for(ApplicationInfo applicationInfo : mAppLocalList) {
1185b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu               AppInfo appInfo = mCache.getEntry(applicationInfo.packageName);
1186afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project               if(appInfo == null) {
1187b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                  Log.i(TAG, " Entry does not exist for pkg:  " + applicationInfo.packageName);
1188afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project               }
1189afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           }
1190afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           if (mAppLocalList.size() > 0) {
1191afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project               sortList(mSortOrder);
1192afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           } else {
1193afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project               notifyDataSetChanged();
1194afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           }
1195afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           showEmptyViewIfListEmpty();
1196afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project           return true;
1197afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1198afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1199afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        private Comparator<ApplicationInfo> getAppComparator(int sortOrder) {
1200afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (sortOrder == SORT_ORDER_ALPHA) {
1201afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return mAlphaComparator;
1202afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1203afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return mSizeComparator;
1204afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1205489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu
1206b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public void bulkUpdateIcons(Map<String, Drawable> icons) {
1207b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (icons == null) {
1208b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                return;
1209b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1210b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            Set<String> keys = icons.keySet();
1211b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            boolean changed = false;
1212b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            for (String key : keys) {
1213b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Drawable ic = icons.get(key);
1214b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (ic != null) {
1215b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    AppInfo aInfo = mCache.getEntry(key);
1216b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if (aInfo != null) {
1217b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        aInfo.refreshIcon(ic);
1218b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        changed = true;
1219b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
1220b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
1221b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1222b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (changed) {
1223b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                notifyDataSetChanged();
1224b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1225b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1226b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1227b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public void bulkUpdateLabels(Map<String, CharSequence> map) {
1228b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (map == null) {
1229b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                return;
1230b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1231b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            Set<String> keys = map.keySet();
1232b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            boolean changed = false;
1233b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            for (String key : keys) {
1234b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                CharSequence label = map.get(key);
1235b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                AppInfo aInfo = mCache.getEntry(key);
1236b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (aInfo != null) {
1237b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    aInfo.refreshLabel(label);
1238b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    changed = true;
1239b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
1240b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1241b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (changed) {
1242b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                notifyDataSetChanged();
1243b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1244b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1245b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
124672ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project        private boolean shouldBeInList(int filterOption, ApplicationInfo info) {
124772ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project            // Match filter here
124872ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project            if (filterOption == FILTER_APPS_RUNNING) {
124972ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                List<ApplicationInfo> runningList = getInstalledApps(FILTER_APPS_RUNNING);
125072ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                for (ApplicationInfo running : runningList) {
125172ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                    if (running.packageName.equalsIgnoreCase(info.packageName)) {
1252e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                        return true;
125372ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                    }
125472ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                }
125572ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project            } else if (filterOption == FILTER_APPS_THIRD_PARTY) {
125672ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1257e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    return true;
125872ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                } else if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
1259e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    return true;
126072ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                }
126172ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project            } else {
126272ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                return true;
126372ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project            }
1264e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            return false;
1265afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1266afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
126772ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project        /*
126872ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project         * Add a package to the current list.
126972ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project         * The package is only added to the displayed list
127072ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project         * based on the filter value. The package is always added to the property map.
127172ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project         * @param pkgName name of package to be added
127272ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project         * @param ps PackageStats of new package
127372ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project         */
1274b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public void addToList(String pkgName, long size, String formattedSize) {
1275b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (pkgName == null) {
1276afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return;
1277afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
127872ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project            // Get ApplicationInfo
127972ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project            ApplicationInfo info = null;
1280afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            try {
1281afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                info = mPm.getApplicationInfo(pkgName, 0);
1282afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } catch (NameNotFoundException e) {
1283afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.w(TAG, "Ignoring non-existent package:"+pkgName);
1284afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return;
1285afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1286afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if(info == null) {
1287afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // Nothing to do log error message and return
1288afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.i(TAG, "Null ApplicationInfo for package:"+pkgName);
1289afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return;
1290afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1291355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            // Add entry to base list
1292e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            mAppList.add(info);
1293e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            // Add entry to map. Note that the index gets adjusted later on based on
1294e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            // whether the newly added package is part of displayed list
1295c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            CharSequence label = info.loadLabel(mPm);
1296b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            mCache.addEntry(new AppInfo(pkgName, -1,
1297c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    label, info.loadIcon(mPm), size, formattedSize));
1298355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            if (addLocalEntry(info, label)) {
1299355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                notifyDataSetChanged();
1300355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            }
1301355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu        }
1302355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu
1303355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu        private boolean addLocalEntry(ApplicationInfo info, CharSequence label) {
1304355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            String pkgName = info.packageName;
130572ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project            // Add to list
1306355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            if (shouldBeInList(mFilterApps, info)) {
130772ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                // Binary search returns a negative index (ie -index) of the position where
130872ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                // this might be inserted.
1309e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                int newIdx = Collections.binarySearch(mAppLocalList, info,
131072ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                        getAppComparator(mSortOrder));
131172ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                if(newIdx >= 0) {
1312355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                    if (localLOGV) Log.i(TAG, "Strange. Package:" + pkgName + " is not new");
1313355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                    return false;
131472ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                }
131572ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                // New entry
131672ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                newIdx = -newIdx-1;
1317c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                addFilterListLocked(newIdx, info, label);
131872ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                // Adjust index
131972ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project                adjustIndex();
1320355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                return true;
132172ed6feab24308a0acd1fa2135afa3476759cf39The Android Open Source Project            }
1322355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu            return false;
1323afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1324b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1325489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu        public void updatePackage(String pkgName,
1326489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                long size, String formattedSize) {
1327489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            ApplicationInfo info = null;
1328489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            try {
1329489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                info = mPm.getApplicationInfo(pkgName,
1330489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                        PackageManager.GET_UNINSTALLED_PACKAGES);
1331489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            } catch (NameNotFoundException e) {
1332489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                return;
1333489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            }
1334489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            AppInfo aInfo = mCache.getEntry(pkgName);
1335489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            if (aInfo != null) {
1336355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                CharSequence label = info.loadLabel(mPm);
1337355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                aInfo.refreshLabel(label);
1338489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                aInfo.refreshIcon(info.loadIcon(mPm));
1339489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                aInfo.setSize(size, formattedSize);
1340355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                // Check if the entry has to be added to the displayed list
1341355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                addLocalEntry(info, label);
1342355b32faa924a0b39067dd759ba03e5af97065caSuchi Amalapurapu                // Refresh list since size might have changed
1343489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                notifyDataSetChanged();
1344489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            }
1345489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu        }
1346489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu
1347e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        private void removePkgBase(String pkgName) {
1348e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            int imax = mAppList.size();
1349e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            for (int i = 0; i < imax; i++) {
1350e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                ApplicationInfo app = mAppList.get(i);
1351e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                if (app.packageName.equalsIgnoreCase(pkgName)) {
1352e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    if (localLOGV) Log.i(TAG, "Removing pkg: "+pkgName+" from base list");
1353e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    mAppList.remove(i);
1354e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                    return;
1355e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project                }
1356e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            }
1357e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
1358b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1359afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public void removeFromList(List<String> pkgNames) {
1360afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if(pkgNames == null) {
1361afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return;
1362afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1363b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if(pkgNames.size()  <= 0) {
1364afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return;
1365afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1366b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            boolean found = false;
1367b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            for (String pkg : pkgNames) {
1368b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                // Remove from the base application list
1369b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                removePkgBase(pkg);
1370b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                // Remove from cache
1371b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (localLOGV) Log.i(TAG, "Removing " + pkg + " from cache");
1372b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                mCache.removeEntry(pkg);
1373b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                // Remove from filtered list
1374c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                if (removeFilterListLocked(pkg)) {
1375c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    found = true;
1376afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
1377afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1378b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            // Adjust indices of list entries
1379afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (found) {
1380afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                adjustIndex();
1381b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (localLOGV) Log.i(TAG, "adjusting index and notifying list view");
1382b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                notifyDataSetChanged();
1383b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1384b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1385b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1386b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public void bulkUpdateSizes(String pkgs[], long sizes[], String formatted[]) {
1387b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if(pkgs == null || sizes == null || formatted == null) {
1388b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                return;
1389b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1390b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            boolean changed = false;
1391b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            for (int i = 0; i < pkgs.length; i++) {
1392b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                AppInfo entry = mCache.getEntry(pkgs[i]);
1393b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (entry == null) {
1394c09326318334904f65d63c485c6fa1a7cb146bd8Suchi Amalapurapu                    if (localLOGV) Log.w(TAG, "Entry for package:"+ pkgs[i] +"doesn't exist in map");
1395b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    continue;
1396b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
1397b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (entry.setSize(sizes[i], formatted[i])) {
1398b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    changed = true;
1399b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
1400b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1401b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (changed) {
1402afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                notifyDataSetChanged();
1403afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1404e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
1405c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu
1406c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        public Filter getFilter() {
1407c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            return mAppFilter;
1408c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        }
1409c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu
1410c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        private class AppFilter extends Filter {
1411c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            @Override
1412c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            protected FilterResults performFiltering(CharSequence prefix) {
1413c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                FilterResults results = new FilterResults();
1414c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                if (prefix == null || prefix.length() == 0) {
1415c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    synchronized (mFilterLock) {
1416c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        results.values = new HashMap<String, String>(mFilterMap);
1417c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        results.count = mFilterMap.size();
1418c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    }
1419c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                } else {
1420c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    final String prefixString = prefix.toString().toLowerCase();
1421c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    Map<String, String> newMap = new HashMap<String, String>();
1422c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    synchronized (mFilterLock) {
1423c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        Map<String, String> localMap = mFilterMap;
1424c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        Set<String> keys = mFilterMap.keySet();
1425c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        for (String key : keys) {
1426c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                            String label = localMap.get(key);
1427c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                            if (label.indexOf(prefixString) != -1) {
1428c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                                newMap.put(key, label);
1429c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                            }
1430c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                        }
1431c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    }
1432c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    results.values = newMap;
1433c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    results.count = newMap.size();
1434c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                }
1435c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                return results;
1436c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            }
1437c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu
1438c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            @Override
1439c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            protected void publishResults(CharSequence constraint, FilterResults results) {
1440c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                mCurrentFilterMap = (Map<String, String>) results.values;
1441c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                reverseGenerateList();
1442c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                if (results.count > 0) {
1443c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    notifyDataSetChanged();
1444c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                } else {
1445c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                    notifyDataSetInvalidated();
1446c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu                }
1447c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu            }
1448c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        }
1449afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1450afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1451afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /*
1452afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Utility method to clear messages to Handler
1453afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * We need'nt synchronize on the Handler since posting messages is guaranteed
1454afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * to be thread safe. Even if the other thread that retrieves package sizes
1455afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * posts a message, we do a cursory check of validity on mAppInfoAdapter's applist
1456afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
1457afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void clearMessagesInHandler() {
1458afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mHandler.removeMessages(INIT_PKG_INFO);
1459b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        mHandler.removeMessages(COMPUTE_BULK_SIZE);
1460afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mHandler.removeMessages(REMOVE_PKG);
1461afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mHandler.removeMessages(REORDER_LIST);
1462afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mHandler.removeMessages(ADD_PKG_START);
1463afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mHandler.removeMessages(ADD_PKG_DONE);
1464b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        mHandler.removeMessages(REFRESH_LABELS);
1465ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        mHandler.removeMessages(REFRESH_DONE);
1466ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        mHandler.removeMessages(NEXT_LOAD_STEP);
1467ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        mHandler.removeMessages(COMPUTE_END);
1468afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1469afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1470afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void sendMessageToHandler(int msgId, int arg1) {
1471afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Message msg = mHandler.obtainMessage(msgId);
1472afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        msg.arg1 = arg1;
1473afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mHandler.sendMessage(msg);
1474afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1475afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1476afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void sendMessageToHandler(int msgId, Bundle data) {
1477afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Message msg = mHandler.obtainMessage(msgId);
1478afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        msg.setData(data);
1479afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mHandler.sendMessage(msg);
1480afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1481afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1482afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void sendMessageToHandler(int msgId) {
1483afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mHandler.sendEmptyMessage(msgId);
1484afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1485afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1486afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /*
1487afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Stats Observer class used to compute package sizes and retrieve size information
1488afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * PkgSizeOberver is the call back thats used when invoking getPackageSizeInfo on
1489afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * PackageManager. The values in call back onGetStatsCompleted are validated
1490afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * and the specified message is passed to mHandler. The package name
1491afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * and the AppInfo object corresponding to the package name are set on the message
1492afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
1493afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    class PkgSizeObserver extends IPackageStatsObserver.Stub {
1494489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu        String pkgName;
1495afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public void onGetStatsCompleted(PackageStats pStats, boolean pSucceeded) {
1496afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if(DEBUG_PKG_DELAY) {
1497afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                try {
1498afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    Thread.sleep(10*1000);
1499afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                } catch (InterruptedException e) {
1500afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
1501afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1502afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            Bundle data = new Bundle();
1503489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            data.putString(ATTR_PKG_NAME, pkgName);
1504b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            data.putBoolean(ATTR_GET_SIZE_STATUS, pSucceeded);
1505afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if(pSucceeded && pStats != null) {
1506489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                if (localLOGV) Log.i(TAG, "onGetStatsCompleted::"+pkgName+", ("+
1507afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        pStats.cacheSize+","+
1508afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        pStats.codeSize+", "+pStats.dataSize);
1509b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                long total = getTotalSize(pStats);
1510b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                data.putLong(ATTR_PKG_STATS, total);
1511b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                CharSequence sizeStr = getSizeStr(total);
1512b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                data.putString(ATTR_PKG_SIZE_STR, sizeStr.toString());
1513afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else {
1514afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.w(TAG, "Invalid package stats from PackageManager");
1515afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1516b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            // Post message to Handler
1517b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            Message msg = mHandler.obtainMessage(ADD_PKG_DONE, data);
1518afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            msg.setData(data);
1519afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mHandler.sendMessage(msg);
1520afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1521afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1522489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu        public void invokeGetSizeInfo(String packageName) {
1523489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            if (packageName == null) {
1524afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return;
1525afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1526489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            pkgName = packageName;
1527afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if(localLOGV) Log.i(TAG, "Invoking getPackageSizeInfo for package:"+
1528489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu                    packageName);
1529489eaccb98c726408d0024376f637b81d8b0314bSuchi Amalapurapu            mPm.getPackageSizeInfo(packageName, this);
1530afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1531afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1532afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1533afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
1534afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Receives notifications when applications are added/removed.
1535afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
1536afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private class PackageIntentReceiver extends BroadcastReceiver {
1537afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         void registerReceiver() {
1538afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project             IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
1539afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project             filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1540afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project             filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
1541afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project             filter.addDataScheme("package");
1542afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project             ManageApplications.this.registerReceiver(this, filter);
1543afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         }
1544afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        @Override
1545afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public void onReceive(Context context, Intent intent) {
1546afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            String actionStr = intent.getAction();
1547afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            Uri data = intent.getData();
1548afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            String pkgName = data.getEncodedSchemeSpecificPart();
1549afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (localLOGV) Log.i(TAG, "action:"+actionStr+", for package:"+pkgName);
1550afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            updatePackageList(actionStr, pkgName);
1551afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1552afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1553afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1554afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void updatePackageList(String actionStr, String pkgName) {
1555afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // technically we dont have to invoke handler since onReceive is invoked on
1556afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // the main thread but doing it here for better clarity
1557afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (Intent.ACTION_PACKAGE_ADDED.equalsIgnoreCase(actionStr)) {
1558afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            Bundle data = new Bundle();
1559afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            data.putString(ATTR_PKG_NAME, pkgName);
1560afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            sendMessageToHandler(ADD_PKG_START, data);
1561afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (Intent.ACTION_PACKAGE_REMOVED.equalsIgnoreCase(actionStr)) {
1562afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            Bundle data = new Bundle();
1563afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            data.putString(ATTR_PKG_NAME, pkgName);
1564afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            sendMessageToHandler(REMOVE_PKG, data);
1565afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1566afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1567b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1568afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
1569afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onCreate(Bundle savedInstanceState) {
1570afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onCreate(savedInstanceState);
1571b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        if(localLOGV) Log.i(TAG, "Activity created");
1572b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        long sCreate;
1573b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        if (DEBUG_TIME) {
1574b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            sCreate = SystemClock.elapsedRealtime();
1575b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1576ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        Intent intent = getIntent();
1577ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        String action = intent.getAction();
1578afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (action.equals(Intent.ACTION_MANAGE_PACKAGE_STORAGE)) {
1579afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mSortOrder = SORT_ORDER_SIZE;
1580afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mSizesFirst = true;
1581afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1582afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mPm = getPackageManager();
1583afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // initialize some window features
1584afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        requestWindowFeature(Window.FEATURE_RIGHT_ICON);
1585afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        requestWindowFeature(Window.FEATURE_PROGRESS);
1586afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
1587afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        setContentView(R.layout.compute_sizes);
1588e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        showLoadingMsg();
1589afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mDefaultAppIcon =Resources.getSystem().getDrawable(
1590afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                com.android.internal.R.drawable.sym_def_app_icon);
1591afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mInvalidSizeStr = getText(R.string.invalid_size_value);
1592afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mComputingSizeStr = getText(R.string.computing_size);
1593afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // initialize the inflater
1594afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
1595afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mReceiver = new PackageIntentReceiver();
1596afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mEmptyView = (TextView) findViewById(R.id.empty_view);
1597afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mObserver = new PkgSizeObserver();
1598afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Create adapter and list view here
1599afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        List<ApplicationInfo> appList = getInstalledApps(mSortOrder);
1600afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mAppInfoAdapter = new AppInfoAdapter(this, appList);
1601afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ListView lv= (ListView) findViewById(android.R.id.list);
1602afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        lv.setOnItemClickListener(this);
1603afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        lv.setSaveEnabled(true);
1604afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        lv.setItemsCanFocus(true);
1605afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        lv.setOnItemClickListener(this);
1606c0b23d3f0bb42b26950512590d5ebd6d3373032dSuchi Amalapurapu        lv.setTextFilterEnabled(true);
1607afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mListView = lv;
1608b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        if (DEBUG_TIME) {
1609b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            Log.i(TAG, "Total time in Activity.create:: " +
1610b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    (SystemClock.elapsedRealtime() - sCreate)+ " ms");
1611b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1612b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        // Get initial info from file for the very first time this activity started
1613b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        long sStart;
1614b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        if (DEBUG_TIME) {
1615b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            sStart = SystemClock.elapsedRealtime();
1616b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1617b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        mCache.loadCache();
1618b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        if (DEBUG_TIME) {
1619b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            Log.i(TAG, "Took " + (SystemClock.elapsedRealtime()-sStart) + " ms to init cache");
1620b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1621afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1622afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1623b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    protected void onDestroy() {
1624b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        // Persist values in cache
1625b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        mCache.updateCache();
1626b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        super.onDestroy();
1627b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    }
1628b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1629afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
1630afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public Dialog onCreateDialog(int id) {
1631afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (id == DLG_LOADING) {
1632afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            ProgressDialog dlg = new ProgressDialog(this);
1633afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
1634afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dlg.setMessage(getText(R.string.loading));
1635afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dlg.setIndeterminate(true);
1636afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dlg.setOnCancelListener(this);
1637afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return dlg;
1638afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1639afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return null;
1640afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1641b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1642afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void showLoadingMsg() {
1643ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        if (DEBUG_TIME) {
1644ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu            mLoadTimeStart = SystemClock.elapsedRealtime();
1645ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        }
1646ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        showDialog(DLG_LOADING);
1647afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if(localLOGV) Log.i(TAG, "Displaying Loading message");
1648afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1649afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1650afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void dismissLoadingMsg() {
1651afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if(localLOGV) Log.i(TAG, "Dismissing Loading message");
1652afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dismissDialog(DLG_LOADING);
1653ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        if (DEBUG_TIME) Log.i(TAG, "Displayed loading message for "+
1654b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                (SystemClock.elapsedRealtime() - mLoadTimeStart) + " ms");
1655afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1656b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1657b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    class AppInfoCache {
1658b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        final static boolean FILE_CACHE = true;
1659b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private static final String mFileCacheName="ManageAppsInfo.txt";
1660b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private static final int FILE_BUFFER_SIZE = 1024;
1661b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private static final boolean DEBUG_CACHE = false;
1662d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu        private static final boolean DEBUG_CACHE_TIME = false;
1663b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private Map<String, AppInfo> mAppPropCache = new HashMap<String, AppInfo>();
1664b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1665b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private boolean isEmpty() {
1666b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            return (mAppPropCache.size() == 0);
1667b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1668b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1669b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private AppInfo getEntry(String pkgName) {
1670b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            return mAppPropCache.get(pkgName);
1671b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1672b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1673b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private Set<String> getPkgList() {
1674b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            return mAppPropCache.keySet();
1675b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1676b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1677b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public void addEntry(AppInfo aInfo) {
1678b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if ((aInfo != null) && (aInfo.pkgName != null)) {
1679b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                mAppPropCache.put(aInfo.pkgName, aInfo);
1680b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1681b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1682b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1683b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public void removeEntry(String pkgName) {
1684b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (pkgName != null) {
1685b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                mAppPropCache.remove(pkgName);
1686b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1687b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1688b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1689b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private void readFromFile() {
1690b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            File cacheFile = new File(getFilesDir(), mFileCacheName);
1691b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (!cacheFile.exists()) {
1692b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                return;
1693b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1694b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            FileInputStream fis = null;
1695b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            boolean err = false;
1696b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            try {
1697b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                fis = new FileInputStream(cacheFile);
1698b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            } catch (FileNotFoundException e) {
1699b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Log.w(TAG, "Error opening file for read operation : " + cacheFile
1700b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        + " with exception " + e);
1701b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                return;
1702b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1703b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            try {
1704b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                byte[] byteBuff = new byte[FILE_BUFFER_SIZE];
1705b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                byte[] lenBytes = new byte[2];
1706b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                mAppPropCache.clear();
1707b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                while(fis.available() > 0) {
1708b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    fis.read(lenBytes, 0, 2);
1709b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    int buffLen = (lenBytes[0] << 8) | lenBytes[1];
1710d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                    if ((buffLen <= 0) || (buffLen > byteBuff.length)) {
1711d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                        err = true;
1712d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                        break;
1713d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                    }
1714b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    // Buffer length cannot be great then max.
1715b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    fis.read(byteBuff, 0, buffLen);
1716b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    String buffStr = new String(byteBuff);
1717b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if (DEBUG_CACHE) {
1718b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        Log.i(TAG, "Read string of len= " + buffLen + " :: " + buffStr + " from file");
1719b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
1720b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    // Parse string for sizes
1721b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    String substrs[] = buffStr.split(",");
1722b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if (substrs.length < 4) {
1723b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        // Something wrong. Bail out and let recomputation proceed.
1724b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        err = true;
1725b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        break;
1726b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
1727b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    long size = -1;
1728b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    int idx = -1;
1729b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    try {
1730b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        size = Long.parseLong(substrs[1]);
1731b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    } catch (NumberFormatException e) {
1732b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        err = true;
1733b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        break;
1734b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
1735b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if (DEBUG_CACHE) {
1736b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        Log.i(TAG, "Creating entry(" + substrs[0] + ", " + idx+"," + size + ", " + substrs[2] + ")");
1737b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
1738b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    AppInfo aInfo = new AppInfo(substrs[0], idx, substrs[3], size, substrs[2]);
1739b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    mAppPropCache.put(aInfo.pkgName, aInfo);
1740b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
1741b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            } catch (IOException e) {
1742b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Log.w(TAG, "Failed reading from file : " + cacheFile + " with exception : " + e);
1743b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                err = true;
1744b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            } finally {
1745b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (fis != null) {
1746b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    try {
1747b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        fis.close();
1748b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    } catch (IOException e) {
1749b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        Log.w(TAG, "Failed to close file " + cacheFile + " with exception : " +e);
1750d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                        err = true;
1751b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
1752b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
1753d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                if (err) {
1754d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                    Log.i(TAG, "Failed to load cache. Not using cache for now.");
1755d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                    // Clear cache and bail out
1756d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                    mAppPropCache.clear();
1757d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                }
1758b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1759b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1760b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1761d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu        boolean writeToFile() {
1762b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            File cacheFile = new File(getFilesDir(), mFileCacheName);
1763b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            FileOutputStream fos = null;
1764b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            try {
1765b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                long opStartTime = SystemClock.uptimeMillis();
1766b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                fos = new FileOutputStream(cacheFile);
1767b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Set<String> keys = mAppPropCache.keySet();
1768b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                byte[] lenBytes = new byte[2];
1769b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                for (String key : keys) {
1770b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    AppInfo aInfo = mAppPropCache.get(key);
1771b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    StringBuilder buff = new StringBuilder(aInfo.pkgName);
1772b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    buff.append(",");
1773b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    buff.append(aInfo.size);
1774b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    buff.append(",");
1775b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    buff.append(aInfo.appSize);
1776b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    buff.append(",");
1777b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    buff.append(aInfo.appName);
1778b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    if (DEBUG_CACHE) {
1779b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        Log.i(TAG, "Writing str : " + buff.toString() + " to file of length:" +
1780b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                                buff.toString().length());
1781b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
1782b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    try {
1783b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        byte[] byteBuff = buff.toString().getBytes();
1784b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        int len = byteBuff.length;
1785b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        if (byteBuff.length >= FILE_BUFFER_SIZE) {
1786b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                            // Truncate the output
1787b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                            len = FILE_BUFFER_SIZE;
1788b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        }
1789b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        // Use 2 bytes to write length
1790b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        lenBytes[1] = (byte) (len & 0x00ff);
1791b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        lenBytes[0] = (byte) ((len & 0x00ff00) >> 8);
1792b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        fos.write(lenBytes, 0, 2);
1793b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        fos.write(byteBuff, 0, len);
1794b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    } catch (IOException e) {
1795b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        Log.w(TAG, "Failed to write to file : " + cacheFile + " with exception : " + e);
1796d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                        return false;
1797b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
1798b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
1799b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (DEBUG_CACHE_TIME) {
1800b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    Log.i(TAG, "Took " + (SystemClock.uptimeMillis() - opStartTime) + " ms to write and process from file");
1801b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
1802d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                return true;
1803b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            } catch (FileNotFoundException e) {
1804b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                Log.w(TAG, "Error opening file for write operation : " + cacheFile+
1805b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        " with exception : " + e);
1806d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                return false;
1807b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            } finally {
1808b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                if (fos != null) {
1809b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    try {
1810b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        fos.close();
1811b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    } catch (IOException e) {
1812b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                        Log.w(TAG, "Failed closing file : " + cacheFile + " with exception : " + e);
1813d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                        return false;
1814b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                    }
1815b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                }
1816b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1817b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1818b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private void loadCache() {
1819d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu             // Restore preferences
1820d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
1821d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            boolean disable = settings.getBoolean(PREF_DISABLE_CACHE, true);
1822d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            if (disable) Log.w(TAG, "Cache has been disabled");
1823d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            // Disable cache till the data is loaded successfully
1824d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            SharedPreferences.Editor editor = settings.edit();
1825d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            editor.putBoolean(PREF_DISABLE_CACHE, true);
1826d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            editor.commit();
1827d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            if (FILE_CACHE && !disable) {
1828b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                readFromFile();
1829d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                // Enable cache since the file has been read successfully
1830d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                editor.putBoolean(PREF_DISABLE_CACHE, false);
1831d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                editor.commit();
1832b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1833b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1834b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1835b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private void updateCache() {
1836d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
1837d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            SharedPreferences.Editor editor = settings.edit();
1838d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            editor.putBoolean(PREF_DISABLE_CACHE, true);
1839d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu            editor.commit();
1840b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            if (FILE_CACHE) {
1841d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                boolean writeStatus = writeToFile();
1842b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu                mAppPropCache.clear();
1843d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                if (writeStatus) {
1844d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                    // Enable cache since the file has been read successfully
1845d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                    editor.putBoolean(PREF_DISABLE_CACHE, false);
1846d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                    editor.commit();
1847d2136f7e5da6d36a685f5bed2727f0abdafb70bfSuchi Amalapurapu                }
1848b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            }
1849b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1850b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    }
1851b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1852afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
1853afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onStart() {
1854afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onStart();
1855b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        // Register receiver
1856afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mReceiver.registerReceiver();
1857e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        sendMessageToHandler(INIT_PKG_INFO);
1858afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1859afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1860afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
1861afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onStop() {
1862afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onStop();
1863ff271ce1b70d6a8c59f3ea8904ef2025061e73f1Suchi Amalapurapu        // Stop the background threads
1864475b58296b0702f54546ae4cd254182ca757eff7Suchi Amalapurapu        if (mResourceThread != null) {
1865475b58296b0702f54546ae4cd254182ca757eff7Suchi Amalapurapu            mResourceThread.setAbort();
1866475b58296b0702f54546ae4cd254182ca757eff7Suchi Amalapurapu        }
1867475b58296b0702f54546ae4cd254182ca757eff7Suchi Amalapurapu        if (mSizeComputor != null) {
1868475b58296b0702f54546ae4cd254182ca757eff7Suchi Amalapurapu            mSizeComputor.setAbort();
1869475b58296b0702f54546ae4cd254182ca757eff7Suchi Amalapurapu        }
1870afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // clear all messages related to application list
1871afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        clearMessagesInHandler();
1872afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // register receiver here
1873b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        unregisterReceiver(mReceiver);
1874afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1875afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1876afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Avoid the restart and pause when orientation changes
1877afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
1878afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
1879afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onConfigurationChanged(newConfig);
1880afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1881afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1882afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /*
1883afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * comparator class used to sort AppInfo objects based on size
1884afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
1885b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    class SizeComparator implements Comparator<ApplicationInfo> {
1886afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public final int compare(ApplicationInfo a, ApplicationInfo b) {
1887b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            AppInfo ainfo = mCache.getEntry(a.packageName);
1888b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            AppInfo binfo = mCache.getEntry(b.packageName);
1889b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            long atotal = ainfo.size;
1890b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            long btotal = binfo.size;
1891afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            long ret = atotal - btotal;
1892afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // negate result to sort in descending order
1893afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (ret < 0) {
1894afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return 1;
1895afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1896afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (ret == 0) {
1897afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return 0;
1898afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1899afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return -1;
1900afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1901afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1902b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1903b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    /*
1904b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu     * Customized comparator class to compare labels.
1905b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu     * Don't use the one defined in ApplicationInfo since that loads the labels again.
1906b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu     */
1907b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    class AlphaComparator implements Comparator<ApplicationInfo> {
1908b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        private final Collator   sCollator = Collator.getInstance();
1909b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1910b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        public final int compare(ApplicationInfo a, ApplicationInfo b) {
1911b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            AppInfo ainfo = mCache.getEntry(a.packageName);
1912b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            AppInfo binfo = mCache.getEntry(b.packageName);
1913b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu            return sCollator.compare(ainfo.appName.toString(), binfo.appName.toString());
1914b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu        }
1915b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu    }
1916b285593cafacc58ecfdf97be395dc8f5a7493051Suchi Amalapurapu
1917afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // utility method used to start sub activity
1918afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void startApplicationDetailsActivity() {
1919afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Create intent to start new activity
1920afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Intent intent = new Intent(Intent.ACTION_VIEW);
1921afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        intent.setClass(this, InstalledAppDetails.class);
1922afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        intent.putExtra(APP_PKG_NAME, mCurrentPkgName);
1923afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // start new activity to display extended information
1924afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        startActivityForResult(intent, INSTALLED_APP_DETAILS);
1925afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1926afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1927afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
1928afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
1929afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        menu.add(0, SORT_ORDER_ALPHA, 1, R.string.sort_order_alpha)
1930afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                .setIcon(android.R.drawable.ic_menu_sort_alphabetically);
1931afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        menu.add(0, SORT_ORDER_SIZE, 2, R.string.sort_order_size)
1932afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                .setIcon(android.R.drawable.ic_menu_sort_by_size);
1933afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        menu.add(0, FILTER_OPTIONS, 3, R.string.filter)
1934afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                .setIcon(R.drawable.ic_menu_filter_settings);
1935afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return true;
1936afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1937afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1938afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
1939afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean onPrepareOptionsMenu(Menu menu) {
1940afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mFirst) {
1941afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            menu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
1942afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            menu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder != SORT_ORDER_SIZE);
1943afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            menu.findItem(FILTER_OPTIONS).setVisible(true);
1944afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return true;
1945afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1946afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return false;
1947afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1948afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1949afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
1950afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
1951afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int menuId = item.getItemId();
1952afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if ((menuId == SORT_ORDER_ALPHA) || (menuId == SORT_ORDER_SIZE)) {
1953afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            sendMessageToHandler(REORDER_LIST, menuId);
1954afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (menuId == FILTER_OPTIONS) {
1955afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (mAlertDlg == null) {
1956afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mAlertDlg = new AlertDialog.Builder(this).
1957afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        setTitle(R.string.filter_dlg_title).
1958afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        setNeutralButton(R.string.cancel, this).
1959afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        setSingleChoiceItems(new CharSequence[] {getText(R.string.filter_apps_all),
1960afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                                getText(R.string.filter_apps_running),
1961afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                                getText(R.string.filter_apps_third_party)},
1962afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                                -1, this).
1963afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        create();
1964afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1965afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mAlertDlg.show();
1966afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1967afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return true;
1968afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1969afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1970afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onItemClick(AdapterView<?> parent, View view, int position,
1971afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            long id) {
1972afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ApplicationInfo info = (ApplicationInfo)mAppInfoAdapter.getItem(position);
1973afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mCurrentPkgName = info.packageName;
1974afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        startApplicationDetailsActivity();
1975afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1976afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1977afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // Finish the activity if the user presses the back button to cancel the activity
1978afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onCancel(DialogInterface dialog) {
1979afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        finish();
1980afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1981afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1982afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onClick(DialogInterface dialog, int which) {
1983afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int newOption;
1984afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        switch (which) {
1985afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Make sure that values of 0, 1, 2 match options all, running, third_party when
1986afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // created via the AlertDialog.Builder
1987afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        case 0:
1988afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            newOption = FILTER_APPS_ALL;
1989afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            break;
1990afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        case 1:
1991afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            newOption = FILTER_APPS_RUNNING;
1992afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            break;
1993afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        case 2:
1994afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            newOption = FILTER_APPS_THIRD_PARTY;
1995afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            break;
1996afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        default:
1997afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return;
1998afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1999afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mAlertDlg.dismiss();
2000afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        sendMessageToHandler(REORDER_LIST, newOption);
2001afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
2002afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
2003