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