Home | History | Annotate | Download | only in applications
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.applications;
     18 
     19 import static android.net.NetworkPolicyManager.POLICY_NONE;
     20 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
     21 
     22 import android.app.Activity;
     23 import android.app.AlertDialog;
     24 import android.app.Fragment;
     25 import android.app.INotificationManager;
     26 import android.content.ComponentName;
     27 import android.content.Context;
     28 import android.content.DialogInterface;
     29 import android.content.Intent;
     30 import android.content.IntentFilter;
     31 import android.content.ServiceConnection;
     32 import android.content.pm.ApplicationInfo;
     33 import android.content.pm.IPackageManager;
     34 import android.content.pm.PackageInfo;
     35 import android.content.pm.PackageManager;
     36 import android.net.NetworkPolicyManager;
     37 import android.os.AsyncTask;
     38 import android.os.Bundle;
     39 import android.os.Environment;
     40 import android.os.Handler;
     41 import android.os.IBinder;
     42 import android.os.RemoteException;
     43 import android.os.ServiceManager;
     44 import android.preference.PreferenceActivity;
     45 import android.preference.PreferenceFrameLayout;
     46 import android.provider.Settings;
     47 import android.support.v4.view.PagerAdapter;
     48 import android.support.v4.view.PagerTabStrip;
     49 import android.support.v4.view.ViewPager;
     50 import android.text.format.Formatter;
     51 import android.util.Log;
     52 import android.view.LayoutInflater;
     53 import android.view.Menu;
     54 import android.view.MenuInflater;
     55 import android.view.MenuItem;
     56 import android.view.View;
     57 import android.view.ViewGroup;
     58 import android.view.animation.AnimationUtils;
     59 import android.widget.AbsListView;
     60 import android.widget.AdapterView;
     61 import android.widget.AdapterView.OnItemClickListener;
     62 import android.widget.BaseAdapter;
     63 import android.widget.Filter;
     64 import android.widget.Filterable;
     65 import android.widget.ListView;
     66 import android.widget.TextView;
     67 
     68 import com.android.internal.app.IMediaContainerService;
     69 import com.android.internal.content.PackageHelper;
     70 import com.android.settings.R;
     71 import com.android.settings.Settings.RunningServicesActivity;
     72 import com.android.settings.Settings.StorageUseActivity;
     73 import com.android.settings.applications.ApplicationsState.AppEntry;
     74 import com.android.settings.deviceinfo.StorageMeasurement;
     75 import com.android.settings.Utils;
     76 
     77 import java.util.ArrayList;
     78 import java.util.Comparator;
     79 import java.util.List;
     80 
     81 final class CanBeOnSdCardChecker {
     82     final IPackageManager mPm;
     83     int mInstallLocation;
     84 
     85     CanBeOnSdCardChecker() {
     86         mPm = IPackageManager.Stub.asInterface(
     87                 ServiceManager.getService("package"));
     88     }
     89 
     90     void init() {
     91         try {
     92             mInstallLocation = mPm.getInstallLocation();
     93         } catch (RemoteException e) {
     94             Log.e("CanBeOnSdCardChecker", "Is Package Manager running?");
     95             return;
     96         }
     97     }
     98 
     99     boolean check(ApplicationInfo info) {
    100         boolean canBe = false;
    101         if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
    102             canBe = true;
    103         } else {
    104             if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
    105                 if (info.installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL ||
    106                         info.installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
    107                     canBe = true;
    108                 } else if (info.installLocation
    109                         == PackageInfo.INSTALL_LOCATION_UNSPECIFIED) {
    110                     if (mInstallLocation == PackageHelper.APP_INSTALL_EXTERNAL) {
    111                         // For apps with no preference and the default value set
    112                         // to install on sdcard.
    113                         canBe = true;
    114                     }
    115                 }
    116             }
    117         }
    118         return canBe;
    119     }
    120 }
    121 
    122 interface AppClickListener {
    123     void onItemClick(ManageApplications.TabInfo tab, AdapterView<?> parent,
    124             View view, int position, long id);
    125 }
    126 
    127 /**
    128  * Activity to pick an application that will be used to display installation information and
    129  * options to uninstall/delete user data for system applications. This activity
    130  * can be launched through Settings or via the ACTION_MANAGE_PACKAGE_STORAGE
    131  * intent.
    132  */
    133 public class ManageApplications extends Fragment implements
    134         AppClickListener, DialogInterface.OnClickListener,
    135         DialogInterface.OnDismissListener {
    136 
    137     static final String TAG = "ManageApplications";
    138     static final boolean DEBUG = false;
    139 
    140     private static final String EXTRA_SORT_ORDER = "sortOrder";
    141     private static final String EXTRA_SHOW_BACKGROUND = "showBackground";
    142     private static final String EXTRA_DEFAULT_LIST_TYPE = "defaultListType";
    143     private static final String EXTRA_RESET_DIALOG = "resetDialog";
    144 
    145     // attributes used as keys when passing values to InstalledAppDetails activity
    146     public static final String APP_CHG = "chg";
    147 
    148     // constant value that can be used to check return code from sub activity.
    149     private static final int INSTALLED_APP_DETAILS = 1;
    150 
    151     public static final int SIZE_TOTAL = 0;
    152     public static final int SIZE_INTERNAL = 1;
    153     public static final int SIZE_EXTERNAL = 2;
    154 
    155     // sort order that can be changed through the menu can be sorted alphabetically
    156     // or size(descending)
    157     private static final int MENU_OPTIONS_BASE = 0;
    158     // Filter options used for displayed list of applications
    159     public static final int FILTER_APPS_ALL = MENU_OPTIONS_BASE + 0;
    160     public static final int FILTER_APPS_THIRD_PARTY = MENU_OPTIONS_BASE + 1;
    161     public static final int FILTER_APPS_SDCARD = MENU_OPTIONS_BASE + 2;
    162 
    163     public static final int SORT_ORDER_ALPHA = MENU_OPTIONS_BASE + 4;
    164     public static final int SORT_ORDER_SIZE = MENU_OPTIONS_BASE + 5;
    165     public static final int SHOW_RUNNING_SERVICES = MENU_OPTIONS_BASE + 6;
    166     public static final int SHOW_BACKGROUND_PROCESSES = MENU_OPTIONS_BASE + 7;
    167     public static final int RESET_APP_PREFERENCES = MENU_OPTIONS_BASE + 8;
    168     // sort order
    169     private int mSortOrder = SORT_ORDER_ALPHA;
    170 
    171     private ApplicationsState mApplicationsState;
    172 
    173     public static class TabInfo implements OnItemClickListener {
    174         public final ManageApplications mOwner;
    175         public final ApplicationsState mApplicationsState;
    176         public final CharSequence mLabel;
    177         public final int mListType;
    178         public final int mFilter;
    179         public final AppClickListener mClickListener;
    180         public final CharSequence mInvalidSizeStr;
    181         public final CharSequence mComputingSizeStr;
    182         private final Bundle mSavedInstanceState;
    183 
    184         public ApplicationsAdapter mApplications;
    185         public LayoutInflater mInflater;
    186         public View mRootView;
    187 
    188         private IMediaContainerService mContainerService;
    189 
    190         private View mLoadingContainer;
    191 
    192         private View mListContainer;
    193 
    194         // ListView used to display list
    195         private ListView mListView;
    196         // Custom view used to display running processes
    197         private RunningProcessesView mRunningProcessesView;
    198 
    199         private LinearColorBar mColorBar;
    200         private TextView mStorageChartLabel;
    201         private TextView mUsedStorageText;
    202         private TextView mFreeStorageText;
    203         private long mFreeStorage = 0, mAppStorage = 0, mTotalStorage = 0;
    204         private long mLastUsedStorage, mLastAppStorage, mLastFreeStorage;
    205 
    206         final Runnable mRunningProcessesAvail = new Runnable() {
    207             public void run() {
    208                 handleRunningProcessesAvail();
    209             }
    210         };
    211 
    212         public TabInfo(ManageApplications owner, ApplicationsState apps,
    213                 CharSequence label, int listType, AppClickListener clickListener,
    214                 Bundle savedInstanceState) {
    215             mOwner = owner;
    216             mApplicationsState = apps;
    217             mLabel = label;
    218             mListType = listType;
    219             switch (listType) {
    220                 case LIST_TYPE_DOWNLOADED: mFilter = FILTER_APPS_THIRD_PARTY; break;
    221                 case LIST_TYPE_SDCARD: mFilter = FILTER_APPS_SDCARD; break;
    222                 default: mFilter = FILTER_APPS_ALL; break;
    223             }
    224             mClickListener = clickListener;
    225             mInvalidSizeStr = owner.getActivity().getText(R.string.invalid_size_value);
    226             mComputingSizeStr = owner.getActivity().getText(R.string.computing_size);
    227             mSavedInstanceState = savedInstanceState;
    228         }
    229 
    230         public void setContainerService(IMediaContainerService containerService) {
    231             mContainerService = containerService;
    232             updateStorageUsage();
    233         }
    234 
    235         public View build(LayoutInflater inflater, ViewGroup contentParent, View contentChild) {
    236             if (mRootView != null) {
    237                 return mRootView;
    238             }
    239 
    240             mInflater = inflater;
    241             mRootView = inflater.inflate(mListType == LIST_TYPE_RUNNING
    242                     ? R.layout.manage_applications_running
    243                     : R.layout.manage_applications_apps, null);
    244             mLoadingContainer = mRootView.findViewById(R.id.loading_container);
    245             mLoadingContainer.setVisibility(View.VISIBLE);
    246             mListContainer = mRootView.findViewById(R.id.list_container);
    247             if (mListContainer != null) {
    248                 // Create adapter and list view here
    249                 View emptyView = mListContainer.findViewById(com.android.internal.R.id.empty);
    250                 ListView lv = (ListView) mListContainer.findViewById(android.R.id.list);
    251                 if (emptyView != null) {
    252                     lv.setEmptyView(emptyView);
    253                 }
    254                 lv.setOnItemClickListener(this);
    255                 lv.setSaveEnabled(true);
    256                 lv.setItemsCanFocus(true);
    257                 lv.setTextFilterEnabled(true);
    258                 mListView = lv;
    259                 mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter);
    260                 mListView.setAdapter(mApplications);
    261                 mListView.setRecyclerListener(mApplications);
    262                 mColorBar = (LinearColorBar)mListContainer.findViewById(R.id.storage_color_bar);
    263                 mStorageChartLabel = (TextView)mListContainer.findViewById(R.id.storageChartLabel);
    264                 mUsedStorageText = (TextView)mListContainer.findViewById(R.id.usedStorageText);
    265                 mFreeStorageText = (TextView)mListContainer.findViewById(R.id.freeStorageText);
    266                 Utils.prepareCustomPreferencesList(contentParent, contentChild, mListView, false);
    267                 if (mFilter == FILTER_APPS_SDCARD) {
    268                     mStorageChartLabel.setText(mOwner.getActivity().getText(
    269                             R.string.sd_card_storage));
    270                 } else {
    271                     mStorageChartLabel.setText(mOwner.getActivity().getText(
    272                             R.string.internal_storage));
    273                 }
    274                 applyCurrentStorage();
    275             }
    276             mRunningProcessesView = (RunningProcessesView)mRootView.findViewById(
    277                     R.id.running_processes);
    278             if (mRunningProcessesView != null) {
    279                 mRunningProcessesView.doCreate(mSavedInstanceState);
    280             }
    281 
    282             return mRootView;
    283         }
    284 
    285         public void detachView() {
    286             if (mRootView != null) {
    287                 ViewGroup group = (ViewGroup)mRootView.getParent();
    288                 if (group != null) {
    289                     group.removeView(mRootView);
    290                 }
    291             }
    292         }
    293 
    294         public void resume(int sortOrder) {
    295             if (mApplications != null) {
    296                 mApplications.resume(sortOrder);
    297             }
    298             if (mRunningProcessesView != null) {
    299                 boolean haveData = mRunningProcessesView.doResume(mOwner, mRunningProcessesAvail);
    300                 if (haveData) {
    301                     mRunningProcessesView.setVisibility(View.VISIBLE);
    302                     mLoadingContainer.setVisibility(View.INVISIBLE);
    303                 } else {
    304                     mLoadingContainer.setVisibility(View.VISIBLE);
    305                 }
    306             }
    307         }
    308 
    309         public void pause() {
    310             if (mApplications != null) {
    311                 mApplications.pause();
    312             }
    313             if (mRunningProcessesView != null) {
    314                 mRunningProcessesView.doPause();
    315             }
    316         }
    317 
    318         void updateStorageUsage() {
    319             // Make sure a callback didn't come at an inopportune time.
    320             if (mOwner.getActivity() == null) return;
    321             // Doesn't make sense for stuff that is not an app list.
    322             if (mApplications == null) return;
    323 
    324             mFreeStorage = 0;
    325             mAppStorage = 0;
    326             mTotalStorage = 0;
    327 
    328             if (mFilter == FILTER_APPS_SDCARD) {
    329                 if (mContainerService != null) {
    330                     try {
    331                         final long[] stats = mContainerService.getFileSystemStats(
    332                                 Environment.getExternalStorageDirectory().getPath());
    333                         mTotalStorage = stats[0];
    334                         mFreeStorage = stats[1];
    335                     } catch (RemoteException e) {
    336                         Log.w(TAG, "Problem in container service", e);
    337                     }
    338                 }
    339 
    340                 if (mApplications != null) {
    341                     final int N = mApplications.getCount();
    342                     for (int i=0; i<N; i++) {
    343                         ApplicationsState.AppEntry ae = mApplications.getAppEntry(i);
    344                         mAppStorage += ae.externalCodeSize + ae.externalDataSize;
    345                     }
    346                 }
    347             } else {
    348                 if (mContainerService != null) {
    349                     try {
    350                         final long[] stats = mContainerService.getFileSystemStats(
    351                                 Environment.getDataDirectory().getPath());
    352                         mTotalStorage = stats[0];
    353                         mFreeStorage = stats[1];
    354                     } catch (RemoteException e) {
    355                         Log.w(TAG, "Problem in container service", e);
    356                     }
    357                 }
    358 
    359                 final boolean emulatedStorage = Environment.isExternalStorageEmulated();
    360                 if (mApplications != null) {
    361                     final int N = mApplications.getCount();
    362                     for (int i=0; i<N; i++) {
    363                         ApplicationsState.AppEntry ae = mApplications.getAppEntry(i);
    364                         mAppStorage += ae.codeSize + ae.dataSize;
    365                         if (emulatedStorage) {
    366                             mAppStorage += ae.externalCodeSize + ae.externalDataSize;
    367                         }
    368                     }
    369                 }
    370                 mFreeStorage += mApplicationsState.sumCacheSizes();
    371             }
    372 
    373             applyCurrentStorage();
    374         }
    375 
    376         void applyCurrentStorage() {
    377             // If view hierarchy is not yet created, no views to update.
    378             if (mRootView == null) {
    379                 return;
    380             }
    381             if (mTotalStorage > 0) {
    382                 mColorBar.setRatios((mTotalStorage-mFreeStorage-mAppStorage)/(float)mTotalStorage,
    383                         mAppStorage/(float)mTotalStorage, mFreeStorage/(float)mTotalStorage);
    384                 long usedStorage = mTotalStorage - mFreeStorage;
    385                 if (mLastUsedStorage != usedStorage) {
    386                     mLastUsedStorage = usedStorage;
    387                     String sizeStr = Formatter.formatShortFileSize(
    388                             mOwner.getActivity(), usedStorage);
    389                     mUsedStorageText.setText(mOwner.getActivity().getResources().getString(
    390                             R.string.service_foreground_processes, sizeStr));
    391                 }
    392                 if (mLastFreeStorage != mFreeStorage) {
    393                     mLastFreeStorage = mFreeStorage;
    394                     String sizeStr = Formatter.formatShortFileSize(
    395                             mOwner.getActivity(), mFreeStorage);
    396                     mFreeStorageText.setText(mOwner.getActivity().getResources().getString(
    397                             R.string.service_background_processes, sizeStr));
    398                 }
    399             } else {
    400                 mColorBar.setRatios(0, 0, 0);
    401                 if (mLastUsedStorage != -1) {
    402                     mLastUsedStorage = -1;
    403                     mUsedStorageText.setText("");
    404                 }
    405                 if (mLastFreeStorage != -1) {
    406                     mLastFreeStorage = -1;
    407                     mFreeStorageText.setText("");
    408                 }
    409             }
    410         }
    411 
    412         @Override
    413         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    414             mClickListener.onItemClick(this, parent, view, position, id);
    415         }
    416 
    417         void handleRunningProcessesAvail() {
    418             mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
    419                     mOwner.getActivity(), android.R.anim.fade_out));
    420             mRunningProcessesView.startAnimation(AnimationUtils.loadAnimation(
    421                     mOwner.getActivity(), android.R.anim.fade_in));
    422             mRunningProcessesView.setVisibility(View.VISIBLE);
    423             mLoadingContainer.setVisibility(View.GONE);
    424         }
    425     }
    426     private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
    427     TabInfo mCurTab = null;
    428 
    429     // Size resource used for packages whose size computation failed for some reason
    430     CharSequence mInvalidSizeStr;
    431     private CharSequence mComputingSizeStr;
    432 
    433     // layout inflater object used to inflate views
    434     private LayoutInflater mInflater;
    435 
    436     private String mCurrentPkgName;
    437 
    438     private Menu mOptionsMenu;
    439 
    440     // These are for keeping track of activity and spinner switch state.
    441     private boolean mActivityResumed;
    442 
    443     static final int LIST_TYPE_DOWNLOADED = 0;
    444     static final int LIST_TYPE_RUNNING = 1;
    445     static final int LIST_TYPE_SDCARD = 2;
    446     static final int LIST_TYPE_ALL = 3;
    447 
    448     private boolean mShowBackground = false;
    449 
    450     private int mDefaultListType = -1;
    451 
    452     private ViewGroup mContentContainer;
    453     private View mRootView;
    454     private ViewPager mViewPager;
    455 
    456     AlertDialog mResetDialog;
    457 
    458     class MyPagerAdapter extends PagerAdapter
    459             implements ViewPager.OnPageChangeListener {
    460         int mCurPos = 0;
    461 
    462         @Override
    463         public int getCount() {
    464             return mTabs.size();
    465         }
    466 
    467         @Override
    468         public Object instantiateItem(ViewGroup container, int position) {
    469             TabInfo tab = mTabs.get(position);
    470             View root = tab.build(mInflater, mContentContainer, mRootView);
    471             container.addView(root);
    472             return root;
    473         }
    474 
    475         @Override
    476         public void destroyItem(ViewGroup container, int position, Object object) {
    477             container.removeView((View)object);
    478         }
    479 
    480         @Override
    481         public boolean isViewFromObject(View view, Object object) {
    482             return view == object;
    483         }
    484 
    485         @Override
    486         public CharSequence getPageTitle(int position) {
    487             return mTabs.get(position).mLabel;
    488         }
    489 
    490         @Override
    491         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    492         }
    493 
    494         @Override
    495         public void onPageSelected(int position) {
    496             mCurPos = position;
    497         }
    498 
    499         @Override
    500         public void onPageScrollStateChanged(int state) {
    501             if (state == ViewPager.SCROLL_STATE_IDLE) {
    502                 updateCurrentTab(mCurPos);
    503             }
    504         }
    505     }
    506 
    507     /*
    508      * Custom adapter implementation for the ListView
    509      * This adapter maintains a map for each displayed application and its properties
    510      * An index value on each AppInfo object indicates the correct position or index
    511      * in the list. If the list gets updated dynamically when the user is viewing the list of
    512      * applications, we need to return the correct index of position. This is done by mapping
    513      * the getId methods via the package name into the internal maps and indices.
    514      * The order of applications in the list is mirrored in mAppLocalList
    515      */
    516     static class ApplicationsAdapter extends BaseAdapter implements Filterable,
    517             ApplicationsState.Callbacks, AbsListView.RecyclerListener {
    518         private final ApplicationsState mState;
    519         private final ApplicationsState.Session mSession;
    520         private final TabInfo mTab;
    521         private final Context mContext;
    522         private final ArrayList<View> mActive = new ArrayList<View>();
    523         private final int mFilterMode;
    524         private ArrayList<ApplicationsState.AppEntry> mBaseEntries;
    525         private ArrayList<ApplicationsState.AppEntry> mEntries;
    526         private boolean mResumed;
    527         private int mLastSortMode=-1;
    528         private boolean mWaitingForData;
    529         private int mWhichSize = SIZE_TOTAL;
    530         CharSequence mCurFilterPrefix;
    531 
    532         private Filter mFilter = new Filter() {
    533             @Override
    534             protected FilterResults performFiltering(CharSequence constraint) {
    535                 ArrayList<ApplicationsState.AppEntry> entries
    536                         = applyPrefixFilter(constraint, mBaseEntries);
    537                 FilterResults fr = new FilterResults();
    538                 fr.values = entries;
    539                 fr.count = entries.size();
    540                 return fr;
    541             }
    542 
    543             @Override
    544             protected void publishResults(CharSequence constraint, FilterResults results) {
    545                 mCurFilterPrefix = constraint;
    546                 mEntries = (ArrayList<ApplicationsState.AppEntry>)results.values;
    547                 notifyDataSetChanged();
    548                 mTab.updateStorageUsage();
    549             }
    550         };
    551 
    552         public ApplicationsAdapter(ApplicationsState state, TabInfo tab, int filterMode) {
    553             mState = state;
    554             mSession = state.newSession(this);
    555             mTab = tab;
    556             mContext = tab.mOwner.getActivity();
    557             mFilterMode = filterMode;
    558         }
    559 
    560         public void resume(int sort) {
    561             if (DEBUG) Log.i(TAG, "Resume!  mResumed=" + mResumed);
    562             if (!mResumed) {
    563                 mResumed = true;
    564                 mSession.resume();
    565                 mLastSortMode = sort;
    566                 rebuild(true);
    567             } else {
    568                 rebuild(sort);
    569             }
    570         }
    571 
    572         public void pause() {
    573             if (mResumed) {
    574                 mResumed = false;
    575                 mSession.pause();
    576             }
    577         }
    578 
    579         public void rebuild(int sort) {
    580             if (sort == mLastSortMode) {
    581                 return;
    582             }
    583             mLastSortMode = sort;
    584             rebuild(true);
    585         }
    586 
    587         public void rebuild(boolean eraseold) {
    588             if (DEBUG) Log.i(TAG, "Rebuilding app list...");
    589             ApplicationsState.AppFilter filterObj;
    590             Comparator<AppEntry> comparatorObj;
    591             boolean emulated = Environment.isExternalStorageEmulated();
    592             if (emulated) {
    593                 mWhichSize = SIZE_TOTAL;
    594             } else {
    595                 mWhichSize = SIZE_INTERNAL;
    596             }
    597             switch (mFilterMode) {
    598                 case FILTER_APPS_THIRD_PARTY:
    599                     filterObj = ApplicationsState.THIRD_PARTY_FILTER;
    600                     break;
    601                 case FILTER_APPS_SDCARD:
    602                     filterObj = ApplicationsState.ON_SD_CARD_FILTER;
    603                     if (!emulated) {
    604                         mWhichSize = SIZE_EXTERNAL;
    605                     }
    606                     break;
    607                 default:
    608                     filterObj = null;
    609                     break;
    610             }
    611             switch (mLastSortMode) {
    612                 case SORT_ORDER_SIZE:
    613                     switch (mWhichSize) {
    614                         case SIZE_INTERNAL:
    615                             comparatorObj = ApplicationsState.INTERNAL_SIZE_COMPARATOR;
    616                             break;
    617                         case SIZE_EXTERNAL:
    618                             comparatorObj = ApplicationsState.EXTERNAL_SIZE_COMPARATOR;
    619                             break;
    620                         default:
    621                             comparatorObj = ApplicationsState.SIZE_COMPARATOR;
    622                             break;
    623                     }
    624                     break;
    625                 default:
    626                     comparatorObj = ApplicationsState.ALPHA_COMPARATOR;
    627                     break;
    628             }
    629             ArrayList<ApplicationsState.AppEntry> entries
    630                     = mSession.rebuild(filterObj, comparatorObj);
    631             if (entries == null && !eraseold) {
    632                 // Don't have new list yet, but can continue using the old one.
    633                 return;
    634             }
    635             mBaseEntries = entries;
    636             if (mBaseEntries != null) {
    637                 mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries);
    638             } else {
    639                 mEntries = null;
    640             }
    641             notifyDataSetChanged();
    642             mTab.updateStorageUsage();
    643 
    644             if (entries == null) {
    645                 mWaitingForData = true;
    646                 mTab.mListContainer.setVisibility(View.INVISIBLE);
    647                 mTab.mLoadingContainer.setVisibility(View.VISIBLE);
    648             } else {
    649                 mTab.mListContainer.setVisibility(View.VISIBLE);
    650                 mTab.mLoadingContainer.setVisibility(View.GONE);
    651             }
    652         }
    653 
    654         ArrayList<ApplicationsState.AppEntry> applyPrefixFilter(CharSequence prefix,
    655                 ArrayList<ApplicationsState.AppEntry> origEntries) {
    656             if (prefix == null || prefix.length() == 0) {
    657                 return origEntries;
    658             } else {
    659                 String prefixStr = ApplicationsState.normalize(prefix.toString());
    660                 final String spacePrefixStr = " " + prefixStr;
    661                 ArrayList<ApplicationsState.AppEntry> newEntries
    662                         = new ArrayList<ApplicationsState.AppEntry>();
    663                 for (int i=0; i<origEntries.size(); i++) {
    664                     ApplicationsState.AppEntry entry = origEntries.get(i);
    665                     String nlabel = entry.getNormalizedLabel();
    666                     if (nlabel.startsWith(prefixStr) || nlabel.indexOf(spacePrefixStr) != -1) {
    667                         newEntries.add(entry);
    668                     }
    669                 }
    670                 return newEntries;
    671             }
    672         }
    673 
    674         @Override
    675         public void onRunningStateChanged(boolean running) {
    676             mTab.mOwner.getActivity().setProgressBarIndeterminateVisibility(running);
    677         }
    678 
    679         @Override
    680         public void onRebuildComplete(ArrayList<AppEntry> apps) {
    681             if (mTab.mLoadingContainer.getVisibility() == View.VISIBLE) {
    682                 mTab.mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
    683                         mContext, android.R.anim.fade_out));
    684                 mTab.mListContainer.startAnimation(AnimationUtils.loadAnimation(
    685                         mContext, android.R.anim.fade_in));
    686             }
    687             mTab.mListContainer.setVisibility(View.VISIBLE);
    688             mTab.mLoadingContainer.setVisibility(View.GONE);
    689             mWaitingForData = false;
    690             mBaseEntries = apps;
    691             mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries);
    692             notifyDataSetChanged();
    693             mTab.updateStorageUsage();
    694         }
    695 
    696         @Override
    697         public void onPackageListChanged() {
    698             rebuild(false);
    699         }
    700 
    701         @Override
    702         public void onPackageIconChanged() {
    703             // We ensure icons are loaded when their item is displayed, so
    704             // don't care about icons loaded in the background.
    705         }
    706 
    707         @Override
    708         public void onPackageSizeChanged(String packageName) {
    709             for (int i=0; i<mActive.size(); i++) {
    710                 AppViewHolder holder = (AppViewHolder)mActive.get(i).getTag();
    711                 if (holder.entry.info.packageName.equals(packageName)) {
    712                     synchronized (holder.entry) {
    713                         holder.updateSizeText(mTab.mInvalidSizeStr, mWhichSize);
    714                     }
    715                     if (holder.entry.info.packageName.equals(mTab.mOwner.mCurrentPkgName)
    716                             && mLastSortMode == SORT_ORDER_SIZE) {
    717                         // We got the size information for the last app the
    718                         // user viewed, and are sorting by size...  they may
    719                         // have cleared data, so we immediately want to resort
    720                         // the list with the new size to reflect it to the user.
    721                         rebuild(false);
    722                     }
    723                     mTab.updateStorageUsage();
    724                     return;
    725                 }
    726             }
    727         }
    728 
    729         @Override
    730         public void onAllSizesComputed() {
    731             if (mLastSortMode == SORT_ORDER_SIZE) {
    732                 rebuild(false);
    733             }
    734             mTab.updateStorageUsage();
    735         }
    736 
    737         public int getCount() {
    738             return mEntries != null ? mEntries.size() : 0;
    739         }
    740 
    741         public Object getItem(int position) {
    742             return mEntries.get(position);
    743         }
    744 
    745         public ApplicationsState.AppEntry getAppEntry(int position) {
    746             return mEntries.get(position);
    747         }
    748 
    749         public long getItemId(int position) {
    750             return mEntries.get(position).id;
    751         }
    752 
    753         public View getView(int position, View convertView, ViewGroup parent) {
    754             // A ViewHolder keeps references to children views to avoid unnecessary calls
    755             // to findViewById() on each row.
    756             AppViewHolder holder = AppViewHolder.createOrRecycle(mTab.mInflater, convertView);
    757             convertView = holder.rootView;
    758 
    759             // Bind the data efficiently with the holder
    760             ApplicationsState.AppEntry entry = mEntries.get(position);
    761             synchronized (entry) {
    762                 holder.entry = entry;
    763                 if (entry.label != null) {
    764                     holder.appName.setText(entry.label);
    765                     holder.appName.setTextColor(mContext.getResources().getColorStateList(
    766                             entry.info.enabled ? android.R.color.primary_text_dark
    767                                     : android.R.color.secondary_text_dark));
    768                 }
    769                 mState.ensureIcon(entry);
    770                 if (entry.icon != null) {
    771                     holder.appIcon.setImageDrawable(entry.icon);
    772                 }
    773                 holder.updateSizeText(mTab.mInvalidSizeStr, mWhichSize);
    774                 if (InstalledAppDetails.SUPPORT_DISABLE_APPS) {
    775                     holder.disabled.setVisibility(entry.info.enabled ? View.GONE : View.VISIBLE);
    776                 } else {
    777                     holder.disabled.setVisibility(View.GONE);
    778                 }
    779                 if (mFilterMode == FILTER_APPS_SDCARD) {
    780                     holder.checkBox.setVisibility(View.VISIBLE);
    781                     holder.checkBox.setChecked((entry.info.flags
    782                             & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
    783                 } else {
    784                     holder.checkBox.setVisibility(View.GONE);
    785                 }
    786             }
    787             mActive.remove(convertView);
    788             mActive.add(convertView);
    789             return convertView;
    790         }
    791 
    792         @Override
    793         public Filter getFilter() {
    794             return mFilter;
    795         }
    796 
    797         @Override
    798         public void onMovedToScrapHeap(View view) {
    799             mActive.remove(view);
    800         }
    801     }
    802 
    803     @Override
    804     public void onCreate(Bundle savedInstanceState) {
    805         super.onCreate(savedInstanceState);
    806 
    807         setHasOptionsMenu(true);
    808 
    809         mApplicationsState = ApplicationsState.getInstance(getActivity().getApplication());
    810         Intent intent = getActivity().getIntent();
    811         String action = intent.getAction();
    812         int defaultListType = LIST_TYPE_DOWNLOADED;
    813         String className = getArguments() != null
    814                 ? getArguments().getString("classname") : null;
    815         if (className == null) {
    816             className = intent.getComponent().getClassName();
    817         }
    818         if (className.equals(RunningServicesActivity.class.getName())
    819                 || className.endsWith(".RunningServices")) {
    820             defaultListType = LIST_TYPE_RUNNING;
    821         } else if (className.equals(StorageUseActivity.class.getName())
    822                 || Intent.ACTION_MANAGE_PACKAGE_STORAGE.equals(action)
    823                 || className.endsWith(".StorageUse")) {
    824             mSortOrder = SORT_ORDER_SIZE;
    825             defaultListType = LIST_TYPE_ALL;
    826         } else if (Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS.equals(action)) {
    827             // Select the all-apps list, with the default sorting
    828             defaultListType = LIST_TYPE_ALL;
    829         }
    830 
    831         if (savedInstanceState != null) {
    832             mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder);
    833             int tmp = savedInstanceState.getInt(EXTRA_DEFAULT_LIST_TYPE, -1);
    834             if (tmp != -1) defaultListType = tmp;
    835             mShowBackground = savedInstanceState.getBoolean(EXTRA_SHOW_BACKGROUND, false);
    836         }
    837 
    838         mDefaultListType = defaultListType;
    839 
    840         final Intent containerIntent = new Intent().setComponent(
    841                 StorageMeasurement.DEFAULT_CONTAINER_COMPONENT);
    842         getActivity().bindService(containerIntent, mContainerConnection, Context.BIND_AUTO_CREATE);
    843 
    844         mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value);
    845         mComputingSizeStr = getActivity().getText(R.string.computing_size);
    846 
    847         TabInfo tab = new TabInfo(this, mApplicationsState,
    848                 getActivity().getString(R.string.filter_apps_third_party),
    849                 LIST_TYPE_DOWNLOADED, this, savedInstanceState);
    850         mTabs.add(tab);
    851 
    852         if (!Environment.isExternalStorageEmulated()) {
    853             tab = new TabInfo(this, mApplicationsState,
    854                     getActivity().getString(R.string.filter_apps_onsdcard),
    855                     LIST_TYPE_SDCARD, this, savedInstanceState);
    856             mTabs.add(tab);
    857         }
    858 
    859         tab = new TabInfo(this, mApplicationsState,
    860                 getActivity().getString(R.string.filter_apps_running),
    861                 LIST_TYPE_RUNNING, this, savedInstanceState);
    862         mTabs.add(tab);
    863 
    864         tab = new TabInfo(this, mApplicationsState,
    865                 getActivity().getString(R.string.filter_apps_all),
    866                 LIST_TYPE_ALL, this, savedInstanceState);
    867         mTabs.add(tab);
    868     }
    869 
    870 
    871     @Override
    872     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    873         // initialize the inflater
    874         mInflater = inflater;
    875 
    876         View rootView = mInflater.inflate(R.layout.manage_applications_content,
    877                 container, false);
    878         mContentContainer = container;
    879         mRootView = rootView;
    880 
    881         mViewPager = (ViewPager) rootView.findViewById(R.id.pager);
    882         MyPagerAdapter adapter = new MyPagerAdapter();
    883         mViewPager.setAdapter(adapter);
    884         mViewPager.setOnPageChangeListener(adapter);
    885         PagerTabStrip tabs = (PagerTabStrip) rootView.findViewById(R.id.tabs);
    886         tabs.setTabIndicatorColorResource(android.R.color.holo_blue_light);
    887 
    888         // We have to do this now because PreferenceFrameLayout looks at it
    889         // only when the view is added.
    890         if (container instanceof PreferenceFrameLayout) {
    891             ((PreferenceFrameLayout.LayoutParams) rootView.getLayoutParams()).removeBorders = true;
    892         }
    893 
    894         if (savedInstanceState != null && savedInstanceState.getBoolean(EXTRA_RESET_DIALOG)) {
    895             buildResetDialog();
    896         }
    897 
    898         if (savedInstanceState == null) {
    899             // First time init: make sure view pager is showing the correct tab.
    900             for (int i = 0; i < mTabs.size(); i++) {
    901                 TabInfo tab = mTabs.get(i);
    902                 if (tab.mListType == mDefaultListType) {
    903                     mViewPager.setCurrentItem(i);
    904                     break;
    905                 }
    906             }
    907         }
    908 
    909         return rootView;
    910     }
    911 
    912     @Override
    913     public void onStart() {
    914         super.onStart();
    915     }
    916 
    917     @Override
    918     public void onResume() {
    919         super.onResume();
    920         mActivityResumed = true;
    921         updateCurrentTab(mViewPager.getCurrentItem());
    922         updateOptionsMenu();
    923     }
    924 
    925     @Override
    926     public void onSaveInstanceState(Bundle outState) {
    927         super.onSaveInstanceState(outState);
    928         outState.putInt(EXTRA_SORT_ORDER, mSortOrder);
    929         if (mDefaultListType != -1) {
    930             outState.putInt(EXTRA_DEFAULT_LIST_TYPE, mDefaultListType);
    931         }
    932         outState.putBoolean(EXTRA_SHOW_BACKGROUND, mShowBackground);
    933         if (mResetDialog != null) {
    934             outState.putBoolean(EXTRA_RESET_DIALOG, true);
    935         }
    936     }
    937 
    938     @Override
    939     public void onPause() {
    940         super.onPause();
    941         mActivityResumed = false;
    942         for (int i=0; i<mTabs.size(); i++) {
    943             mTabs.get(i).pause();
    944         }
    945     }
    946 
    947     @Override
    948     public void onStop() {
    949         super.onStop();
    950         if (mResetDialog != null) {
    951             mResetDialog.dismiss();
    952             mResetDialog = null;
    953         }
    954     }
    955 
    956     @Override
    957     public void onDestroyView() {
    958         super.onDestroyView();
    959 
    960         // We are going to keep the tab data structures around, but they
    961         // are no longer attached to their view hierarchy.
    962         for (int i=0; i<mTabs.size(); i++) {
    963             mTabs.get(i).detachView();
    964         }
    965     }
    966 
    967     @Override
    968     public void onActivityResult(int requestCode, int resultCode, Intent data) {
    969         if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
    970             mApplicationsState.requestSize(mCurrentPkgName);
    971         }
    972     }
    973 
    974     TabInfo tabForType(int type) {
    975         for (int i = 0; i < mTabs.size(); i++) {
    976             TabInfo tab = mTabs.get(i);
    977             if (tab.mListType == type) {
    978                 return tab;
    979             }
    980         }
    981         return null;
    982     }
    983 
    984     // utility method used to start sub activity
    985     private void startApplicationDetailsActivity() {
    986         // start new fragment to display extended information
    987         Bundle args = new Bundle();
    988         args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mCurrentPkgName);
    989 
    990         PreferenceActivity pa = (PreferenceActivity)getActivity();
    991         pa.startPreferencePanel(InstalledAppDetails.class.getName(), args,
    992                 R.string.application_info_label, null, this, INSTALLED_APP_DETAILS);
    993     }
    994 
    995     @Override
    996     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    997         Log.i(TAG, "onCreateOptionsMenu in " + this + ": " + menu);
    998         mOptionsMenu = menu;
    999         // note: icons removed for now because the cause the new action
   1000         // bar UI to be very confusing.
   1001         menu.add(0, SORT_ORDER_ALPHA, 1, R.string.sort_order_alpha)
   1002                 //.setIcon(android.R.drawable.ic_menu_sort_alphabetically)
   1003                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
   1004         menu.add(0, SORT_ORDER_SIZE, 2, R.string.sort_order_size)
   1005                 //.setIcon(android.R.drawable.ic_menu_sort_by_size)
   1006                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
   1007         menu.add(0, SHOW_RUNNING_SERVICES, 3, R.string.show_running_services)
   1008                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
   1009         menu.add(0, SHOW_BACKGROUND_PROCESSES, 3, R.string.show_background_processes)
   1010                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
   1011         menu.add(0, RESET_APP_PREFERENCES, 4, R.string.reset_app_preferences)
   1012                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
   1013         updateOptionsMenu();
   1014     }
   1015 
   1016     @Override
   1017     public void onPrepareOptionsMenu(Menu menu) {
   1018         updateOptionsMenu();
   1019     }
   1020 
   1021     @Override
   1022     public void onDestroyOptionsMenu() {
   1023         mOptionsMenu = null;
   1024     }
   1025 
   1026     @Override
   1027     public void onDestroy() {
   1028         getActivity().unbindService(mContainerConnection);
   1029         super.onDestroy();
   1030     }
   1031 
   1032     void updateOptionsMenu() {
   1033         if (mOptionsMenu == null) {
   1034             return;
   1035         }
   1036 
   1037         /*
   1038          * The running processes screen doesn't use the mApplicationsAdapter
   1039          * so bringing up this menu in that case doesn't make any sense.
   1040          */
   1041         if (mCurTab != null && mCurTab.mListType == LIST_TYPE_RUNNING) {
   1042             TabInfo tab = tabForType(LIST_TYPE_RUNNING);
   1043             boolean showingBackground = tab != null && tab.mRunningProcessesView != null
   1044                     ? tab.mRunningProcessesView.mAdapter.getShowBackground() : false;
   1045             mOptionsMenu.findItem(SORT_ORDER_ALPHA).setVisible(false);
   1046             mOptionsMenu.findItem(SORT_ORDER_SIZE).setVisible(false);
   1047             mOptionsMenu.findItem(SHOW_RUNNING_SERVICES).setVisible(showingBackground);
   1048             mOptionsMenu.findItem(SHOW_BACKGROUND_PROCESSES).setVisible(!showingBackground);
   1049             mOptionsMenu.findItem(RESET_APP_PREFERENCES).setVisible(false);
   1050         } else {
   1051             mOptionsMenu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
   1052             mOptionsMenu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder != SORT_ORDER_SIZE);
   1053             mOptionsMenu.findItem(SHOW_RUNNING_SERVICES).setVisible(false);
   1054             mOptionsMenu.findItem(SHOW_BACKGROUND_PROCESSES).setVisible(false);
   1055             mOptionsMenu.findItem(RESET_APP_PREFERENCES).setVisible(true);
   1056         }
   1057     }
   1058 
   1059     void buildResetDialog() {
   1060         if (mResetDialog == null) {
   1061             AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
   1062             builder.setTitle(R.string.reset_app_preferences_title);
   1063             builder.setMessage(R.string.reset_app_preferences_desc);
   1064             builder.setPositiveButton(R.string.reset_app_preferences_button, this);
   1065             builder.setNegativeButton(R.string.cancel, null);
   1066             mResetDialog = builder.show();
   1067             mResetDialog.setOnDismissListener(this);
   1068         }
   1069     }
   1070 
   1071     @Override
   1072     public void onDismiss(DialogInterface dialog) {
   1073         if (mResetDialog == dialog) {
   1074             mResetDialog = null;
   1075         }
   1076     }
   1077 
   1078 
   1079     @Override
   1080     public void onClick(DialogInterface dialog, int which) {
   1081         if (mResetDialog == dialog) {
   1082             final PackageManager pm = getActivity().getPackageManager();
   1083             final INotificationManager nm = INotificationManager.Stub.asInterface(
   1084                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
   1085             final NetworkPolicyManager npm = NetworkPolicyManager.from(getActivity());
   1086             final Handler handler = new Handler(getActivity().getMainLooper());
   1087             (new AsyncTask<Void, Void, Void>() {
   1088                 @Override protected Void doInBackground(Void... params) {
   1089                     List<ApplicationInfo> apps = pm.getInstalledApplications(
   1090                             PackageManager.GET_DISABLED_COMPONENTS);
   1091                     for (int i=0; i<apps.size(); i++) {
   1092                         ApplicationInfo app = apps.get(i);
   1093                         try {
   1094                             if (DEBUG) Log.v(TAG, "Enabling notifications: " + app.packageName);
   1095                             nm.setNotificationsEnabledForPackage(app.packageName, true);
   1096                         } catch (android.os.RemoteException ex) {
   1097                         }
   1098                         if (DEBUG) Log.v(TAG, "Clearing preferred: " + app.packageName);
   1099                         pm.clearPackagePreferredActivities(app.packageName);
   1100                         if (!app.enabled) {
   1101                             if (DEBUG) Log.v(TAG, "Enabling app: " + app.packageName);
   1102                             if (pm.getApplicationEnabledSetting(app.packageName)
   1103                                     == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
   1104                                 pm.setApplicationEnabledSetting(app.packageName,
   1105                                         PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
   1106                                         PackageManager.DONT_KILL_APP);
   1107                             }
   1108                         }
   1109                     }
   1110                     // We should have cleared all of the preferred apps above;
   1111                     // just in case some may be lingering, retrieve whatever is
   1112                     // still set and remove it.
   1113                     ArrayList<IntentFilter> filters = new ArrayList<IntentFilter>();
   1114                     ArrayList<ComponentName> prefActivities = new ArrayList<ComponentName>();
   1115                     pm.getPreferredActivities(filters, prefActivities, null);
   1116                     for (int i=0; i<prefActivities.size(); i++) {
   1117                         if (DEBUG) Log.v(TAG, "Clearing preferred: "
   1118                                 + prefActivities.get(i).getPackageName());
   1119                         pm.clearPackagePreferredActivities(prefActivities.get(i).getPackageName());
   1120                     }
   1121                     final int[] restrictedAppIds = npm.getAppsWithPolicy(
   1122                             POLICY_REJECT_METERED_BACKGROUND);
   1123                     for (int i : restrictedAppIds) {
   1124                         if (DEBUG) Log.v(TAG, "Clearing data policy: " + i);
   1125                         npm.setAppPolicy(i, POLICY_NONE);
   1126                     }
   1127                     handler.post(new Runnable() {
   1128                         @Override public void run() {
   1129                             if (DEBUG) Log.v(TAG, "Done clearing");
   1130                             if (getActivity() != null && mActivityResumed) {
   1131                                 if (DEBUG) Log.v(TAG, "Updating UI!");
   1132                                 for (int i=0; i<mTabs.size(); i++) {
   1133                                     TabInfo tab = mTabs.get(i);
   1134                                     if (tab.mApplications != null) {
   1135                                         tab.mApplications.pause();
   1136                                     }
   1137                                 }
   1138                                 if (mCurTab != null) {
   1139                                     mCurTab.resume(mSortOrder);
   1140                                 }
   1141                             }
   1142                         }
   1143                     });
   1144                     return null;
   1145                 }
   1146             }).execute();
   1147         }
   1148     }
   1149 
   1150     @Override
   1151     public boolean onOptionsItemSelected(MenuItem item) {
   1152         int menuId = item.getItemId();
   1153         if ((menuId == SORT_ORDER_ALPHA) || (menuId == SORT_ORDER_SIZE)) {
   1154             mSortOrder = menuId;
   1155             if (mCurTab != null && mCurTab.mApplications != null) {
   1156                 mCurTab.mApplications.rebuild(mSortOrder);
   1157             }
   1158         } else if (menuId == SHOW_RUNNING_SERVICES) {
   1159             mShowBackground = false;
   1160             if (mCurTab != null && mCurTab.mRunningProcessesView != null) {
   1161                 mCurTab.mRunningProcessesView.mAdapter.setShowBackground(false);
   1162             }
   1163         } else if (menuId == SHOW_BACKGROUND_PROCESSES) {
   1164             mShowBackground = true;
   1165             if (mCurTab != null && mCurTab.mRunningProcessesView != null) {
   1166                 mCurTab.mRunningProcessesView.mAdapter.setShowBackground(true);
   1167             }
   1168         } else if (menuId == RESET_APP_PREFERENCES) {
   1169             buildResetDialog();
   1170         } else {
   1171             // Handle the home button
   1172             return false;
   1173         }
   1174         updateOptionsMenu();
   1175         return true;
   1176     }
   1177 
   1178     public void onItemClick(TabInfo tab, AdapterView<?> parent, View view, int position,
   1179             long id) {
   1180         if (tab.mApplications != null && tab.mApplications.getCount() > position) {
   1181             ApplicationsState.AppEntry entry = tab.mApplications.getAppEntry(position);
   1182             mCurrentPkgName = entry.info.packageName;
   1183             startApplicationDetailsActivity();
   1184         }
   1185     }
   1186 
   1187     public void updateCurrentTab(int position) {
   1188         TabInfo tab = mTabs.get(position);
   1189         mCurTab = tab;
   1190 
   1191         // Put things in the correct paused/resumed state.
   1192         if (mActivityResumed) {
   1193             mCurTab.build(mInflater, mContentContainer, mRootView);
   1194             mCurTab.resume(mSortOrder);
   1195         } else {
   1196             mCurTab.pause();
   1197         }
   1198         for (int i=0; i<mTabs.size(); i++) {
   1199             TabInfo t = mTabs.get(i);
   1200             if (t != mCurTab) {
   1201                 t.pause();
   1202             }
   1203         }
   1204 
   1205         mCurTab.updateStorageUsage();
   1206         updateOptionsMenu();
   1207         final Activity host = getActivity();
   1208         if (host != null) {
   1209             host.invalidateOptionsMenu();
   1210         }
   1211     }
   1212 
   1213     private volatile IMediaContainerService mContainerService;
   1214 
   1215     private final ServiceConnection mContainerConnection = new ServiceConnection() {
   1216         @Override
   1217         public void onServiceConnected(ComponentName name, IBinder service) {
   1218             mContainerService = IMediaContainerService.Stub.asInterface(service);
   1219             for (int i=0; i<mTabs.size(); i++) {
   1220                 mTabs.get(i).setContainerService(mContainerService);
   1221             }
   1222         }
   1223 
   1224         @Override
   1225         public void onServiceDisconnected(ComponentName name) {
   1226             mContainerService = null;
   1227         }
   1228     };
   1229 }
   1230