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