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