summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/applications/ManageApplications.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/settings/applications/ManageApplications.java')
-rw-r--r--src/com/android/settings/applications/ManageApplications.java1252
1 files changed, 383 insertions, 869 deletions
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 555d18c..14d48c8 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -16,40 +16,22 @@
package com.android.settings.applications;
-import static android.net.NetworkPolicyManager.POLICY_NONE;
-import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
-
import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.AppOpsManager;
import android.app.Fragment;
-import android.app.INotificationManager;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
-import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.res.TypedArray;
-import android.net.NetworkPolicyManager;
import android.net.Uri;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
-import android.os.Handler;
-import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.os.UserManager;
import android.preference.PreferenceFrameLayout;
import android.provider.Settings;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.PagerTabStrip;
-import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -61,34 +43,35 @@ import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ListView;
import android.widget.Spinner;
-import com.android.internal.app.IMediaContainerService;
import com.android.internal.content.PackageHelper;
import com.android.settings.R;
-import com.android.settings.Settings.RunningServicesActivity;
-import com.android.settings.Settings.StorageUseActivity;
+import com.android.settings.Settings.AllApplicationsActivity;
+import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.applications.ApplicationsState.AppEntry;
-import com.android.settings.deviceinfo.StorageMeasurement;
+import com.android.settings.applications.ApplicationsState.AppFilter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
-import java.util.List;
final class CanBeOnSdCardChecker {
final IPackageManager mPm;
int mInstallLocation;
-
+
CanBeOnSdCardChecker() {
mPm = IPackageManager.Stub.asInterface(
ServiceManager.getService("package"));
}
-
+
void init() {
try {
mInstallLocation = mPm.getInstallLocation();
@@ -97,7 +80,7 @@ final class CanBeOnSdCardChecker {
return;
}
}
-
+
boolean check(ApplicationInfo info) {
boolean canBe = false;
if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
@@ -121,414 +104,407 @@ final class CanBeOnSdCardChecker {
}
}
-interface AppClickListener {
- void onItemClick(ManageApplications.TabInfo tab, AdapterView<?> parent,
- View view, int position, long id);
-}
-
/**
* Activity to pick an application that will be used to display installation information and
* options to uninstall/delete user data for system applications. This activity
* can be launched through Settings or via the ACTION_MANAGE_PACKAGE_STORAGE
* intent.
*/
-public class ManageApplications extends Fragment implements
- AppClickListener, DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
+public class ManageApplications extends Fragment implements OnItemClickListener,
+ OnItemSelectedListener {
static final String TAG = "ManageApplications";
- static final boolean DEBUG = false;
+ static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final String EXTRA_LIST_TYPE = "currentListType";
private static final String EXTRA_SORT_ORDER = "sortOrder";
- private static final String EXTRA_SHOW_BACKGROUND = "showBackground";
- private static final String EXTRA_DEFAULT_LIST_TYPE = "defaultListType";
- private static final String EXTRA_RESET_DIALOG = "resetDialog";
// attributes used as keys when passing values to InstalledAppDetails activity
public static final String APP_CHG = "chg";
// constant value that can be used to check return code from sub activity.
private static final int INSTALLED_APP_DETAILS = 1;
+ private static final int ADVANCED_SETTINGS = 2;
public static final int SIZE_TOTAL = 0;
public static final int SIZE_INTERNAL = 1;
public static final int SIZE_EXTERNAL = 2;
+ // Filter options used for displayed list of applications
+ // The order which they appear is the order they will show when spinner is present.
+ public static final int FILTER_APPS_DOWNLOADED_AND_LAUNCHER = 0;
+ public static final int FILTER_APPS_ALL = 1;
+ public static final int FILTER_APPS_ENABLED = 2;
+ public static final int FILTER_APPS_DISABLED = 3;
+ public static final int FILTER_APPS_PERSONAL = 4;
+ public static final int FILTER_APPS_WORK = 5;
+
+ // This is the string labels for the filter modes above, the order must be kept in sync.
+ public static final int[] FILTER_LABELS = new int[] {
+ R.string.filter_all_apps, // Downloaded and launcher, spinner not shown in this case
+ R.string.filter_all_apps, // All apps
+ R.string.filter_enabled_apps, // Enabled
+ R.string.filter_apps_disabled, // Disabled
+ R.string.filter_personal_apps, // Personal
+ R.string.filter_work_apps, // Work
+ };
+ // This is the actual mapping to filters from FILTER_ constants above, the order must
+ // be kept in sync.
+ public static final AppFilter[] FILTERS = new AppFilter[] {
+ ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER, // Downloaded and launcher
+ ApplicationsState.FILTER_EVERYTHING, // All apps
+ ApplicationsState.FILTER_ALL_ENABLED, // Enabled
+ ApplicationsState.FILTER_DISABLED, // Disabled
+ ApplicationsState.FILTER_PERSONAL, // Personal
+ ApplicationsState.FILTER_WORK, // Work
+ };
+
// sort order that can be changed through the menu can be sorted alphabetically
// or size(descending)
private static final int MENU_OPTIONS_BASE = 0;
- // Filter options used for displayed list of applications
- public static final int FILTER_APPS_ALL = MENU_OPTIONS_BASE + 0;
- public static final int FILTER_APPS_THIRD_PARTY = MENU_OPTIONS_BASE + 1;
- public static final int FILTER_APPS_SDCARD = MENU_OPTIONS_BASE + 2;
- public static final int FILTER_APPS_DISABLED = MENU_OPTIONS_BASE + 3;
-
- public static final int SORT_ORDER_ALPHA = MENU_OPTIONS_BASE + 4;
- public static final int SORT_ORDER_SIZE = MENU_OPTIONS_BASE + 5;
- public static final int SHOW_RUNNING_SERVICES = MENU_OPTIONS_BASE + 6;
- public static final int SHOW_BACKGROUND_PROCESSES = MENU_OPTIONS_BASE + 7;
- public static final int RESET_APP_PREFERENCES = MENU_OPTIONS_BASE + 8;
+ public static final int SORT_ORDER_ALPHA = MENU_OPTIONS_BASE + 1;
+ public static final int SORT_ORDER_SIZE = MENU_OPTIONS_BASE + 2;
+ public static final int RESET_APP_PREFERENCES = MENU_OPTIONS_BASE + 3;
// sort order
private int mSortOrder = SORT_ORDER_ALPHA;
-
+
private ApplicationsState mApplicationsState;
- public static class TabInfo implements OnItemClickListener {
- public final ManageApplications mOwner;
- public final ApplicationsState mApplicationsState;
- public final CharSequence mLabel;
- public final int mListType;
- public final int mFilter;
- public final AppClickListener mClickListener;
- public final CharSequence mInvalidSizeStr;
- public final CharSequence mComputingSizeStr;
- private final Bundle mSavedInstanceState;
-
- public ApplicationsAdapter mApplications;
- public LayoutInflater mInflater;
- public View mRootView;
-
- private IMediaContainerService mContainerService;
-
- private View mLoadingContainer;
-
- private View mListContainer;
-
- // ListView used to display list
- private ListView mListView;
- // Custom view used to display running processes
- private RunningProcessesView mRunningProcessesView;
-
- //private LinearColorBar mColorBar;
- //private TextView mStorageChartLabel;
- //private TextView mUsedStorageText;
- //private TextView mFreeStorageText;
- private long mFreeStorage = 0, mAppStorage = 0, mTotalStorage = 0;
- private long mLastUsedStorage, mLastAppStorage, mLastFreeStorage;
-
- final Runnable mRunningProcessesAvail = new Runnable() {
- public void run() {
- handleRunningProcessesAvail();
- }
- };
+ public int mListType;
+ public int mFilter;
- public TabInfo(ManageApplications owner, ApplicationsState apps,
- CharSequence label, int listType, AppClickListener clickListener,
- Bundle savedInstanceState) {
- mOwner = owner;
- mApplicationsState = apps;
- mLabel = label;
- mListType = listType;
- switch (listType) {
- case LIST_TYPE_DOWNLOADED: mFilter = FILTER_APPS_THIRD_PARTY; break;
- case LIST_TYPE_SDCARD: mFilter = FILTER_APPS_SDCARD; break;
- case LIST_TYPE_DISABLED: mFilter = FILTER_APPS_DISABLED; break;
- default: mFilter = FILTER_APPS_ALL; break;
- }
- mClickListener = clickListener;
- mInvalidSizeStr = owner.getActivity().getText(R.string.invalid_size_value);
- mComputingSizeStr = owner.getActivity().getText(R.string.computing_size);
- mSavedInstanceState = savedInstanceState;
+ public ApplicationsAdapter mApplications;
+
+ private View mLoadingContainer;
+
+ private View mListContainer;
+
+ // ListView used to display list
+ private ListView mListView;
+
+ // Size resource used for packages whose size computation failed for some reason
+ CharSequence mInvalidSizeStr;
+
+ // layout inflater object used to inflate views
+ private LayoutInflater mInflater;
+
+ private String mCurrentPkgName;
+ private int mCurrentUid;
+
+ private Menu mOptionsMenu;
+
+ public static final int LIST_TYPE_MAIN = 0;
+ public static final int LIST_TYPE_ALL = 1;
+
+ private View mRootView;
+
+ private View mSpinnerHeader;
+ private Spinner mFilterSpinner;
+ private FilterSpinnerAdapter mFilterAdapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ mApplicationsState = ApplicationsState.getInstance(getActivity().getApplication());
+
+ Intent intent = getActivity().getIntent();
+ String action = intent.getAction();
+ String className = getArguments() != null
+ ? getArguments().getString("classname") : null;
+ if (className == null) {
+ className = intent.getComponent().getClassName();
}
+ if (Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS.equals(action)
+ || className.equals(AllApplicationsActivity.class.getName())) {
+ mListType = LIST_TYPE_ALL;
+ } else {
+ mListType = LIST_TYPE_MAIN;
+ }
+ mFilter = getDefaultFilter();
- public void setContainerService(IMediaContainerService containerService) {
- mContainerService = containerService;
- updateStorageUsage();
+ if (savedInstanceState != null) {
+ mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder);
}
- public View build(LayoutInflater inflater, ViewGroup contentParent, View contentChild) {
- if (mRootView != null) {
- return mRootView;
- }
- mInflater = inflater;
- mRootView = inflater.inflate(mListType == LIST_TYPE_RUNNING
- ? R.layout.manage_applications_running
- : R.layout.manage_applications_apps, null);
- mLoadingContainer = mRootView.findViewById(R.id.loading_container);
- mLoadingContainer.setVisibility(View.VISIBLE);
- mListContainer = mRootView.findViewById(R.id.list_container);
- if (mListContainer != null) {
- // Create adapter and list view here
- View emptyView = mListContainer.findViewById(com.android.internal.R.id.empty);
- ListView lv = (ListView) mListContainer.findViewById(android.R.id.list);
- if (emptyView != null) {
- lv.setEmptyView(emptyView);
- }
- lv.setOnItemClickListener(this);
- lv.setSaveEnabled(true);
- lv.setItemsCanFocus(true);
- lv.setTextFilterEnabled(true);
- mListView = lv;
- mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter);
- mListView.setAdapter(mApplications);
- mListView.setRecyclerListener(mApplications);
- //mColorBar = (LinearColorBar)mListContainer.findViewById(R.id.storage_color_bar);
- //mStorageChartLabel = (TextView)mListContainer.findViewById(R.id.storageChartLabel);
- //mUsedStorageText = (TextView)mListContainer.findViewById(R.id.usedStorageText);
- //mFreeStorageText = (TextView)mListContainer.findViewById(R.id.freeStorageText);
- Utils.prepareCustomPreferencesList(contentParent, contentChild, mListView, false);
- if (mFilter == FILTER_APPS_SDCARD) {
- //mStorageChartLabel.setText(mOwner.getActivity().getText(
- // R.string.sd_card_storage));
- } else {
- //mStorageChartLabel.setText(mOwner.getActivity().getText(
- // R.string.internal_storage));
- }
- applyCurrentStorage();
- }
- mRunningProcessesView = (RunningProcessesView)mRootView.findViewById(
- R.id.running_processes);
- if (mRunningProcessesView != null) {
- mRunningProcessesView.doCreate(mSavedInstanceState);
+ mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value);
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // initialize the inflater
+ mInflater = inflater;
+
+ createHeader();
+
+ mRootView = inflater.inflate(R.layout.manage_applications_apps, null);
+ mLoadingContainer = mRootView.findViewById(R.id.loading_container);
+ mLoadingContainer.setVisibility(View.VISIBLE);
+ mListContainer = mRootView.findViewById(R.id.list_container);
+ if (mListContainer != null) {
+ // Create adapter and list view here
+ View emptyView = mListContainer.findViewById(com.android.internal.R.id.empty);
+ ListView lv = (ListView) mListContainer.findViewById(android.R.id.list);
+ if (emptyView != null) {
+ lv.setEmptyView(emptyView);
}
+ lv.setOnItemClickListener(this);
+ lv.setSaveEnabled(true);
+ lv.setItemsCanFocus(true);
+ lv.setTextFilterEnabled(true);
+ mListView = lv;
+ mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter);
+ mListView.setAdapter(mApplications);
+ mListView.setRecyclerListener(mApplications);
- return mRootView;
+ Utils.prepareCustomPreferencesList(container, mRootView, mListView, false);
}
- public void detachView() {
- if (mRootView != null) {
- ViewGroup group = (ViewGroup)mRootView.getParent();
- if (group != null) {
- group.removeView(mRootView);
- }
- }
+ // We have to do this now because PreferenceFrameLayout looks at it
+ // only when the view is added.
+ if (container instanceof PreferenceFrameLayout) {
+ ((PreferenceFrameLayout.LayoutParams) mRootView.getLayoutParams()).removeBorders = true;
}
- public void resume(int sortOrder) {
- if (mApplications != null) {
- mApplications.resume(sortOrder);
- }
- if (mRunningProcessesView != null) {
- boolean haveData = mRunningProcessesView.doResume(mOwner, mRunningProcessesAvail);
- if (haveData) {
- mRunningProcessesView.setVisibility(View.VISIBLE);
- mLoadingContainer.setVisibility(View.INVISIBLE);
- } else {
- mLoadingContainer.setVisibility(View.VISIBLE);
- }
+ return mRootView;
+ }
+
+ private void createHeader() {
+ Activity activity = getActivity();
+ View content = activity.findViewById(R.id.main_content);
+ ViewGroup contentParent = (ViewGroup) content.getParent();
+ mSpinnerHeader = (ViewGroup) activity.getLayoutInflater()
+ .inflate(R.layout.apps_filter_spinner, contentParent, false);
+ mFilterSpinner = (Spinner) mSpinnerHeader.findViewById(R.id.filter_spinner);
+ mFilterAdapter = new FilterSpinnerAdapter(this);
+ mFilterSpinner.setAdapter(mFilterAdapter);
+ mFilterSpinner.setOnItemSelectedListener(this);
+ contentParent.addView(mSpinnerHeader, 0);
+
+ mFilterAdapter.enableFilter(getDefaultFilter());
+ if (mListType != LIST_TYPE_MAIN) {
+ if (UserManager.get(getActivity()).getUserProfiles().size() > 1) {
+ mFilterAdapter.enableFilter(FILTER_APPS_PERSONAL);
+ mFilterAdapter.enableFilter(FILTER_APPS_WORK);
}
}
+ }
- public void pause() {
- if (mApplications != null) {
- mApplications.pause();
- }
- if (mRunningProcessesView != null) {
- mRunningProcessesView.doPause();
- }
+ private int getDefaultFilter() {
+ if (mListType == LIST_TYPE_MAIN) {
+ return FILTER_APPS_DOWNLOADED_AND_LAUNCHER;
}
+ return FILTER_APPS_ALL;
+ }
- public void release() {
- if (mApplications != null) {
- mApplications.release();
- }
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateView();
+ updateOptionsMenu();
+ if (mApplications != null) {
+ mApplications.resume(mSortOrder);
}
+ }
- void updateStorageUsage() {
- // Make sure a callback didn't come at an inopportune time.
- if (mOwner.getActivity() == null) return;
- // Doesn't make sense for stuff that is not an app list.
- if (mApplications == null) return;
-
- mFreeStorage = 0;
- mAppStorage = 0;
- mTotalStorage = 0;
-
- if (mFilter == FILTER_APPS_SDCARD) {
- if (mContainerService != null) {
- try {
- final long[] stats = mContainerService.getFileSystemStats(
- Environment.getExternalStorageDirectory().getPath());
- mTotalStorage = stats[0];
- mFreeStorage = stats[1];
- } catch (RemoteException e) {
- Log.w(TAG, "Problem in container service", e);
- }
- }
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(EXTRA_SORT_ORDER, mSortOrder);
+ }
- if (mApplications != null) {
- final int N = mApplications.getCount();
- for (int i=0; i<N; i++) {
- ApplicationsState.AppEntry ae = mApplications.getAppEntry(i);
- mAppStorage += ae.externalCodeSize + ae.externalDataSize
- + ae.externalCacheSize;
- }
- }
- } else {
- if (mContainerService != null) {
- try {
- final long[] stats = mContainerService.getFileSystemStats(
- Environment.getDataDirectory().getPath());
- mTotalStorage = stats[0];
- mFreeStorage = stats[1];
- } catch (RemoteException e) {
- Log.w(TAG, "Problem in container service", e);
- }
- }
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mApplications != null) {
+ mApplications.pause();
+ }
+ }
- final boolean emulatedStorage = Environment.isExternalStorageEmulated();
- if (mApplications != null) {
- final int N = mApplications.getCount();
- for (int i=0; i<N; i++) {
- ApplicationsState.AppEntry ae = mApplications.getAppEntry(i);
- mAppStorage += ae.codeSize + ae.dataSize;
- if (emulatedStorage) {
- mAppStorage += ae.externalCodeSize + ae.externalDataSize;
- }
- }
- }
- mFreeStorage += mApplicationsState.sumCacheSizes();
- }
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
- applyCurrentStorage();
+ if (mApplications != null) {
+ mApplications.release();
}
+ mRootView = null;
+ }
- void applyCurrentStorage() {
- // If view hierarchy is not yet created, no views to update.
- if (mRootView == null) {
- return;
- }
- /*
- if (mTotalStorage > 0) {
- BidiFormatter bidiFormatter = BidiFormatter.getInstance();
- mColorBar.setRatios((mTotalStorage-mFreeStorage-mAppStorage)/(float)mTotalStorage,
- mAppStorage/(float)mTotalStorage, mFreeStorage/(float)mTotalStorage);
- long usedStorage = mTotalStorage - mFreeStorage;
- if (mLastUsedStorage != usedStorage) {
- mLastUsedStorage = usedStorage;
- String sizeStr = bidiFormatter.unicodeWrap(
- Formatter.formatShortFileSize(mOwner.getActivity(), usedStorage));
- mUsedStorageText.setText(mOwner.getActivity().getResources().getString(
- R.string.service_foreground_processes, sizeStr));
- }
- if (mLastFreeStorage != mFreeStorage) {
- mLastFreeStorage = mFreeStorage;
- String sizeStr = bidiFormatter.unicodeWrap(
- Formatter.formatShortFileSize(mOwner.getActivity(), mFreeStorage));
- mFreeStorageText.setText(mOwner.getActivity().getResources().getString(
- R.string.service_background_processes, sizeStr));
- }
- } else {
- mColorBar.setRatios(0, 0, 0);
- if (mLastUsedStorage != -1) {
- mLastUsedStorage = -1;
- mUsedStorageText.setText("");
- }
- if (mLastFreeStorage != -1) {
- mLastFreeStorage = -1;
- mFreeStorageText.setText("");
- }
- }
- */
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
+ mApplicationsState.requestSize(mCurrentPkgName, UserHandle.getUserId(mCurrentUid));
}
+ }
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- mClickListener.onItemClick(this, parent, view, position, id);
- }
+ // utility method used to start sub activity
+ private void startApplicationDetailsActivity() {
+ // TODO: Figure out if there is a way where we can spin up the profile's settings
+ // process ahead of time, to avoid a long load of data when user clicks on a managed app.
+ // Maybe when they load the list of apps that contains managed profile apps.
+ Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ intent.setData(Uri.fromParts("package", mCurrentPkgName, null));
+ getActivity().startActivityAsUser(intent,
+ new UserHandle(UserHandle.getUserId(mCurrentUid)));
+ }
- void handleRunningProcessesAvail() {
- mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
- mOwner.getActivity(), android.R.anim.fade_out));
- mRunningProcessesView.startAnimation(AnimationUtils.loadAnimation(
- mOwner.getActivity(), android.R.anim.fade_in));
- mRunningProcessesView.setVisibility(View.VISIBLE);
- mLoadingContainer.setVisibility(View.GONE);
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ mOptionsMenu = menu;
+ if (mListType == LIST_TYPE_MAIN) {
+ // Only show advanced options when in the main app list (from dashboard).
+ inflater.inflate(R.menu.manage_apps, menu);
}
+ menu.add(0, SORT_ORDER_ALPHA, 1, R.string.sort_order_alpha)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ menu.add(0, SORT_ORDER_SIZE, 2, R.string.sort_order_size)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ updateOptionsMenu();
}
- private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
- private int mNumTabs;
- TabInfo mCurTab = null;
- // Size resource used for packages whose size computation failed for some reason
- CharSequence mInvalidSizeStr;
- private CharSequence mComputingSizeStr;
-
- // layout inflater object used to inflate views
- private LayoutInflater mInflater;
-
- private String mCurrentPkgName;
- private int mCurrentUid;
-
- private Menu mOptionsMenu;
+ @Override
+ public void onPrepareOptionsMenu(Menu menu) {
+ updateOptionsMenu();
+ }
+
+ @Override
+ public void onDestroyOptionsMenu() {
+ mOptionsMenu = null;
+ }
- // These are for keeping track of activity and spinner switch state.
- private boolean mActivityResumed;
+ void updateOptionsMenu() {
+ if (mOptionsMenu == null) {
+ return;
+ }
+
+ if (mListType != LIST_TYPE_MAIN) {
+ // Allow sorting except on main apps list.
+ mOptionsMenu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
+ mOptionsMenu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder != SORT_ORDER_SIZE);
+ } else {
+ mOptionsMenu.findItem(SORT_ORDER_ALPHA).setVisible(false);
+ mOptionsMenu.findItem(SORT_ORDER_SIZE).setVisible(false);
+ }
+ }
- private static final int LIST_TYPE_MISSING = -1;
- static final int LIST_TYPE_DOWNLOADED = 0;
- static final int LIST_TYPE_RUNNING = 1;
- static final int LIST_TYPE_SDCARD = 2;
- static final int LIST_TYPE_ALL = 3;
- static final int LIST_TYPE_DISABLED = 4;
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int menuId = item.getItemId();
+ switch(item.getItemId()) {
+ case SORT_ORDER_ALPHA:
+ case SORT_ORDER_SIZE:
+ mSortOrder = menuId;
+ if (mApplications != null) {
+ mApplications.rebuild(mSortOrder);
+ }
+ break;
+ case R.id.advanced:
+ ((SettingsActivity) getActivity()).startPreferencePanel(
+ AdvancedAppSettings.class.getName(), null, R.string.advanced_apps,
+ null, this, ADVANCED_SETTINGS);
+ return true;
+ default:
+ // Handle the home button
+ return false;
+ }
+ updateOptionsMenu();
+ return true;
+ }
- private boolean mShowBackground = false;
-
- private int mDefaultListType = -1;
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ if (mApplications != null && mApplications.getCount() > position) {
+ ApplicationsState.AppEntry entry = mApplications.getAppEntry(position);
+ mCurrentPkgName = entry.info.packageName;
+ mCurrentUid = entry.info.uid;
+ startApplicationDetailsActivity();
+ }
+ }
- private ViewGroup mContentContainer;
- private View mRootView;
- private ViewPager mViewPager;
- private ViewGroup mPinnedHeader;
- private Spinner mSpinner;
- private Context mContext;
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ mApplications.setFilter(mFilterAdapter.getFilter(position));
+ }
- AlertDialog mResetDialog;
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
- class MyPagerAdapter extends PagerAdapter
- implements ViewPager.OnPageChangeListener {
- int mCurPos = 0;
+ public void updateView() {
+ updateOptionsMenu();
+ final Activity host = getActivity();
+ if (host != null) {
+ host.invalidateOptionsMenu();
+ }
+ }
- @Override
- public int getCount() {
- return mNumTabs;
+ public void setHasDisabled(boolean hasDisabledApps) {
+ if (mListType == LIST_TYPE_MAIN) {
+ // No filtering on main app list.
+ return;
}
-
- @Override
- public Object instantiateItem(ViewGroup container, int position) {
- TabInfo tab = mTabs.get(position);
- View root = tab.build(mInflater, mContentContainer, mRootView);
- container.addView(root);
- root.setTag(R.id.name, tab);
- return root;
+ if (hasDisabledApps) {
+ mFilterAdapter.enableFilter(FILTER_APPS_ENABLED);
+ mFilterAdapter.enableFilter(FILTER_APPS_DISABLED);
+ } else {
+ mFilterAdapter.disableFilter(FILTER_APPS_ENABLED);
+ mFilterAdapter.disableFilter(FILTER_APPS_DISABLED);
}
+ }
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- container.removeView((View)object);
+ static class FilterSpinnerAdapter extends ArrayAdapter<CharSequence> {
+
+ private final ManageApplications mManageApplications;
+
+ // Use ArrayAdapter for view logic, but have our own list for managing
+ // the options available.
+ private final ArrayList<Integer> mFilterOptions = new ArrayList<>();
+
+ public FilterSpinnerAdapter(ManageApplications manageApplications) {
+ super(manageApplications.getActivity(), R.layout.filter_spinner_item);
+ setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mManageApplications = manageApplications;
}
- @Override
- public boolean isViewFromObject(View view, Object object) {
- return view == object;
+ public int getFilter(int position) {
+ return mFilterOptions.get(position);
}
- @Override
- public int getItemPosition(Object object) {
- return super.getItemPosition(object);
- //return ((TabInfo)((View)object).getTag(R.id.name)).mListType;
+ public void enableFilter(int filter) {
+ if (mFilterOptions.contains(filter)) return;
+ mFilterOptions.add(filter);
+ Collections.sort(mFilterOptions);
+ mManageApplications.mSpinnerHeader.setVisibility(
+ mFilterOptions.size() > 1 ? View.VISIBLE : View.GONE);
+ notifyDataSetChanged();
}
- @Override
- public CharSequence getPageTitle(int position) {
- return mTabs.get(position).mLabel;
+ public void disableFilter(int filter) {
+ if (!mFilterOptions.remove((Integer) filter)) {
+ return;
+ }
+ Collections.sort(mFilterOptions);
+ mManageApplications.mSpinnerHeader.setVisibility(
+ mFilterOptions.size() > 1 ? View.VISIBLE : View.GONE);
+ notifyDataSetChanged();
}
@Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ public int getCount() {
+ return mFilterOptions.size();
}
@Override
- public void onPageSelected(int position) {
- mCurPos = position;
+ public CharSequence getItem(int position) {
+ return getFilterString(mFilterOptions.get(position));
}
- @Override
- public void onPageScrollStateChanged(int state) {
- if (state == ViewPager.SCROLL_STATE_IDLE) {
- updateCurrentTab(mCurPos);
- }
+ private CharSequence getFilterString(int filter) {
+ return mManageApplications.getString(FILTER_LABELS[filter]);
}
+
}
/*
@@ -544,15 +520,14 @@ public class ManageApplications extends Fragment implements
ApplicationsState.Callbacks, AbsListView.RecyclerListener {
private final ApplicationsState mState;
private final ApplicationsState.Session mSession;
- private final TabInfo mTab;
+ private final ManageApplications mManageApplications;
private final Context mContext;
private final ArrayList<View> mActive = new ArrayList<View>();
- private final int mFilterMode;
+ private int mFilterMode;
private ArrayList<ApplicationsState.AppEntry> mBaseEntries;
private ArrayList<ApplicationsState.AppEntry> mEntries;
private boolean mResumed;
private int mLastSortMode=-1;
- private boolean mWaitingForData;
private int mWhichSize = SIZE_TOTAL;
CharSequence mCurFilterPrefix;
@@ -568,22 +543,28 @@ public class ManageApplications extends Fragment implements
}
@Override
+ @SuppressWarnings("unchecked")
protected void publishResults(CharSequence constraint, FilterResults results) {
mCurFilterPrefix = constraint;
- mEntries = (ArrayList<ApplicationsState.AppEntry>)results.values;
+ mEntries = (ArrayList<ApplicationsState.AppEntry>) results.values;
notifyDataSetChanged();
- mTab.updateStorageUsage();
}
};
- public ApplicationsAdapter(ApplicationsState state, TabInfo tab, int filterMode) {
+ public ApplicationsAdapter(ApplicationsState state, ManageApplications manageApplications,
+ int filterMode) {
mState = state;
mSession = state.newSession(this);
- mTab = tab;
- mContext = tab.mOwner.getActivity();
+ mManageApplications = manageApplications;
+ mContext = manageApplications.getActivity();
mFilterMode = filterMode;
}
+ public void setFilter(int filter) {
+ mFilterMode = filter;
+ rebuild(true);
+ }
+
public void resume(int sort) {
if (DEBUG) Log.i(TAG, "Resume! mResumed=" + mResumed);
if (!mResumed) {
@@ -614,7 +595,7 @@ public class ManageApplications extends Fragment implements
mLastSortMode = sort;
rebuild(true);
}
-
+
public void rebuild(boolean eraseold) {
if (DEBUG) Log.i(TAG, "Rebuilding app list...");
ApplicationsState.AppFilter filterObj;
@@ -625,23 +606,7 @@ public class ManageApplications extends Fragment implements
} else {
mWhichSize = SIZE_INTERNAL;
}
- switch (mFilterMode) {
- case FILTER_APPS_THIRD_PARTY:
- filterObj = ApplicationsState.THIRD_PARTY_FILTER;
- break;
- case FILTER_APPS_SDCARD:
- filterObj = ApplicationsState.ON_SD_CARD_FILTER;
- if (!emulated) {
- mWhichSize = SIZE_EXTERNAL;
- }
- break;
- case FILTER_APPS_DISABLED:
- filterObj = ApplicationsState.DISABLED_FILTER;
- break;
- default:
- filterObj = ApplicationsState.ALL_ENABLED_FILTER;
- break;
- }
+ filterObj = FILTERS[mFilterMode];
switch (mLastSortMode) {
case SORT_ORDER_SIZE:
switch (mWhichSize) {
@@ -673,16 +638,26 @@ public class ManageApplications extends Fragment implements
mEntries = null;
}
notifyDataSetChanged();
- mTab.updateStorageUsage();
if (entries == null) {
- mWaitingForData = true;
- mTab.mListContainer.setVisibility(View.INVISIBLE);
- mTab.mLoadingContainer.setVisibility(View.VISIBLE);
+ mManageApplications.mListContainer.setVisibility(View.INVISIBLE);
+ mManageApplications.mLoadingContainer.setVisibility(View.VISIBLE);
} else {
- mTab.mListContainer.setVisibility(View.VISIBLE);
- mTab.mLoadingContainer.setVisibility(View.GONE);
+ mManageApplications.mListContainer.setVisibility(View.VISIBLE);
+ mManageApplications.mLoadingContainer.setVisibility(View.GONE);
}
+
+ mManageApplications.setHasDisabled(hasDisabledApps());
+ }
+
+ private boolean hasDisabledApps() {
+ ArrayList<AppEntry> allApps = mSession.getAllApps();
+ for (int i = 0; i < allApps.size(); i++) {
+ if (!allApps.get(i).info.enabled) {
+ return true;
+ }
+ }
+ return false;
}
ArrayList<ApplicationsState.AppEntry> applyPrefixFilter(CharSequence prefix,
@@ -707,24 +682,22 @@ public class ManageApplications extends Fragment implements
@Override
public void onRunningStateChanged(boolean running) {
- mTab.mOwner.getActivity().setProgressBarIndeterminateVisibility(running);
+ mManageApplications.getActivity().setProgressBarIndeterminateVisibility(running);
}
@Override
public void onRebuildComplete(ArrayList<AppEntry> apps) {
- if (mTab.mLoadingContainer.getVisibility() == View.VISIBLE) {
- mTab.mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
+ if (mManageApplications.mLoadingContainer.getVisibility() == View.VISIBLE) {
+ mManageApplications.mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
mContext, android.R.anim.fade_out));
- mTab.mListContainer.startAnimation(AnimationUtils.loadAnimation(
+ mManageApplications.mListContainer.startAnimation(AnimationUtils.loadAnimation(
mContext, android.R.anim.fade_in));
}
- mTab.mListContainer.setVisibility(View.VISIBLE);
- mTab.mLoadingContainer.setVisibility(View.GONE);
- mWaitingForData = false;
+ mManageApplications.mListContainer.setVisibility(View.VISIBLE);
+ mManageApplications.mLoadingContainer.setVisibility(View.GONE);
mBaseEntries = apps;
mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries);
notifyDataSetChanged();
- mTab.updateStorageUsage();
}
@Override
@@ -744,9 +717,9 @@ public class ManageApplications extends Fragment implements
AppViewHolder holder = (AppViewHolder)mActive.get(i).getTag();
if (holder.entry.info.packageName.equals(packageName)) {
synchronized (holder.entry) {
- holder.updateSizeText(mTab.mInvalidSizeStr, mWhichSize);
+ holder.updateSizeText(mManageApplications.mInvalidSizeStr, mWhichSize);
}
- if (holder.entry.info.packageName.equals(mTab.mOwner.mCurrentPkgName)
+ if (holder.entry.info.packageName.equals(mManageApplications.mCurrentPkgName)
&& mLastSortMode == SORT_ORDER_SIZE) {
// We got the size information for the last app the
// user viewed, and are sorting by size... they may
@@ -754,28 +727,33 @@ public class ManageApplications extends Fragment implements
// the list with the new size to reflect it to the user.
rebuild(false);
}
- mTab.updateStorageUsage();
return;
}
}
}
@Override
+ public void onLauncherInfoChanged() {
+ if (mFilterMode == FILTER_APPS_DOWNLOADED_AND_LAUNCHER) {
+ rebuild(false);
+ }
+ }
+
+ @Override
public void onAllSizesComputed() {
if (mLastSortMode == SORT_ORDER_SIZE) {
rebuild(false);
}
- mTab.updateStorageUsage();
}
-
+
public int getCount() {
return mEntries != null ? mEntries.size() : 0;
}
-
+
public Object getItem(int position) {
return mEntries.get(position);
}
-
+
public ApplicationsState.AppEntry getAppEntry(int position) {
return mEntries.get(position);
}
@@ -783,11 +761,12 @@ public class ManageApplications extends Fragment implements
public long getItemId(int position) {
return mEntries.get(position).id;
}
-
+
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unnecessary calls
// to findViewById() on each row.
- AppViewHolder holder = AppViewHolder.createOrRecycle(mTab.mInflater, convertView);
+ AppViewHolder holder = AppViewHolder.createOrRecycle(mManageApplications.mInflater,
+ convertView);
convertView = holder.rootView;
// Bind the data efficiently with the holder
@@ -801,7 +780,7 @@ public class ManageApplications extends Fragment implements
if (entry.icon != null) {
holder.appIcon.setImageDrawable(entry.icon);
}
- holder.updateSizeText(mTab.mInvalidSizeStr, mWhichSize);
+ holder.updateSizeText(mManageApplications.mInvalidSizeStr, mWhichSize);
if ((entry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
holder.disabled.setVisibility(View.VISIBLE);
holder.disabled.setText(R.string.not_installed);
@@ -811,13 +790,7 @@ public class ManageApplications extends Fragment implements
} else {
holder.disabled.setVisibility(View.GONE);
}
- if (mFilterMode == FILTER_APPS_SDCARD) {
- holder.checkBox.setVisibility(View.VISIBLE);
- holder.checkBox.setChecked((entry.info.flags
- & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
- } else {
- holder.checkBox.setVisibility(View.GONE);
- }
+ holder.checkBox.setVisibility(View.GONE);
}
mActive.remove(convertView);
mActive.add(convertView);
@@ -834,463 +807,4 @@ public class ManageApplications extends Fragment implements
mActive.remove(view);
}
}
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setHasOptionsMenu(true);
-
- mContext = getActivity();
- mApplicationsState = ApplicationsState.getInstance(getActivity().getApplication());
- Intent intent = getActivity().getIntent();
- String action = intent.getAction();
- int defaultListType = LIST_TYPE_DOWNLOADED;
- String className = getArguments() != null
- ? getArguments().getString("classname") : null;
- if (className == null) {
- className = intent.getComponent().getClassName();
- }
- if (className.equals(RunningServicesActivity.class.getName())
- || className.endsWith(".RunningServices")) {
- defaultListType = LIST_TYPE_RUNNING;
- } else if (className.equals(StorageUseActivity.class.getName())
- || Intent.ACTION_MANAGE_PACKAGE_STORAGE.equals(action)
- || className.endsWith(".StorageUse")) {
- mSortOrder = SORT_ORDER_SIZE;
- defaultListType = LIST_TYPE_ALL;
- } else if (android.provider.Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS.equals(action)) {
- // Select the all-apps list, with the default sorting
- defaultListType = LIST_TYPE_ALL;
- }
-
- if (savedInstanceState != null) {
- mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder);
- int tmp = savedInstanceState.getInt(EXTRA_DEFAULT_LIST_TYPE, -1);
- if (tmp != -1) defaultListType = tmp;
- mShowBackground = savedInstanceState.getBoolean(EXTRA_SHOW_BACKGROUND, false);
- }
-
- mDefaultListType = defaultListType;
-
- final Intent containerIntent = new Intent().setComponent(
- StorageMeasurement.DEFAULT_CONTAINER_COMPONENT);
- getActivity().bindService(containerIntent, mContainerConnection, Context.BIND_AUTO_CREATE);
-
- mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value);
- mComputingSizeStr = getActivity().getText(R.string.computing_size);
-
- TabInfo tab = new TabInfo(this, mApplicationsState,
- getActivity().getString(R.string.filter_apps_third_party),
- LIST_TYPE_DOWNLOADED, this, savedInstanceState);
- mTabs.add(tab);
-
- if (!Environment.isExternalStorageEmulated()) {
- tab = new TabInfo(this, mApplicationsState,
- getActivity().getString(R.string.filter_apps_onsdcard),
- LIST_TYPE_SDCARD, this, savedInstanceState);
- mTabs.add(tab);
- }
-
- tab = new TabInfo(this, mApplicationsState,
- getActivity().getString(R.string.filter_apps_running),
- LIST_TYPE_RUNNING, this, savedInstanceState);
- mTabs.add(tab);
-
- tab = new TabInfo(this, mApplicationsState,
- getActivity().getString(R.string.filter_apps_all),
- LIST_TYPE_ALL, this, savedInstanceState);
- mTabs.add(tab);
-
- tab = new TabInfo(this, mApplicationsState,
- getActivity().getString(R.string.filter_apps_disabled),
- LIST_TYPE_DISABLED, this, savedInstanceState);
- mTabs.add(tab);
-
- mNumTabs = mTabs.size();
- }
-
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- // initialize the inflater
- mInflater = inflater;
-
- View rootView = mInflater.inflate(R.layout.manage_applications_content,
- container, false);
- mContentContainer = container;
- mRootView = rootView;
- mViewPager = (ViewPager) rootView.findViewById(R.id.pager);
- MyPagerAdapter adapter = new MyPagerAdapter();
- mViewPager.setAdapter(adapter);
- mViewPager.setOnPageChangeListener(adapter);
- PagerTabStrip tabs = (PagerTabStrip) rootView.findViewById(R.id.tabs);
-
- // This should be set in the XML layout, but PagerTabStrip lives in
- // support-v4 and doesn't have styleable attributes.
- final TypedArray ta = tabs.getContext().obtainStyledAttributes(
- new int[] { android.R.attr.colorAccent });
- final int colorAccent = ta.getColor(0, 0);
- ta.recycle();
-
- tabs.setTabIndicatorColorResource(colorAccent);
-
- // We have to do this now because PreferenceFrameLayout looks at it
- // only when the view is added.
- if (container instanceof PreferenceFrameLayout) {
- ((PreferenceFrameLayout.LayoutParams) rootView.getLayoutParams()).removeBorders = true;
- }
-
- if (savedInstanceState != null && savedInstanceState.getBoolean(EXTRA_RESET_DIALOG)) {
- buildResetDialog();
- }
-
- if (savedInstanceState == null) {
- // First time init: make sure view pager is showing the correct tab.
- int extraCurrentListType = getActivity().getIntent().getIntExtra(EXTRA_LIST_TYPE,
- LIST_TYPE_MISSING);
- int currentListType = (extraCurrentListType != LIST_TYPE_MISSING)
- ? extraCurrentListType : mDefaultListType;
- for (int i = 0; i < mNumTabs; i++) {
- TabInfo tab = mTabs.get(i);
- if (tab.mListType == currentListType) {
- mViewPager.setCurrentItem(i);
- break;
- }
- }
- }
-
- return rootView;
- }
-
- @Override
- public void onStart() {
- super.onStart();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mActivityResumed = true;
- updateCurrentTab(mViewPager.getCurrentItem());
- updateNumTabs();
- updateOptionsMenu();
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putInt(EXTRA_SORT_ORDER, mSortOrder);
- if (mDefaultListType != -1) {
- outState.putInt(EXTRA_DEFAULT_LIST_TYPE, mDefaultListType);
- }
- outState.putBoolean(EXTRA_SHOW_BACKGROUND, mShowBackground);
- if (mResetDialog != null) {
- outState.putBoolean(EXTRA_RESET_DIALOG, true);
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mActivityResumed = false;
- for (int i=0; i<mTabs.size(); i++) {
- mTabs.get(i).pause();
- }
- }
-
- @Override
- public void onStop() {
- super.onStop();
- if (mResetDialog != null) {
- mResetDialog.dismiss();
- mResetDialog = null;
- }
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
-
- // We are going to keep the tab data structures around, but they
- // are no longer attached to their view hierarchy.
- for (int i=0; i<mTabs.size(); i++) {
- mTabs.get(i).detachView();
- mTabs.get(i).release();
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
- mApplicationsState.requestSize(mCurrentPkgName, UserHandle.getUserId(mCurrentUid));
- }
- }
-
- private void updateNumTabs() {
- int newNum = mApplicationsState.haveDisabledApps() ? mTabs.size() : (mTabs.size()-1);
- if (newNum != mNumTabs) {
- mNumTabs = newNum;
- if (mViewPager != null) {
- mViewPager.getAdapter().notifyDataSetChanged();
- }
- }
- }
-
- TabInfo tabForType(int type) {
- for (int i = 0; i < mTabs.size(); i++) {
- TabInfo tab = mTabs.get(i);
- if (tab.mListType == type) {
- return tab;
- }
- }
- return null;
- }
-
- // utility method used to start sub activity
- private void startApplicationDetailsActivity() {
- // TODO: Figure out if there is a way where we can spin up the profile's settings
- // process ahead of time, to avoid a long load of data when user clicks on a managed app.
- // Maybe when they load the list of apps that contains managed profile apps.
- Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
- intent.setData(Uri.fromParts("package", mCurrentPkgName, null));
- getActivity().startActivityAsUser(intent,
- new UserHandle(UserHandle.getUserId(mCurrentUid)));
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- mOptionsMenu = menu;
- // note: icons removed for now because the cause the new action
- // bar UI to be very confusing.
- menu.add(0, SORT_ORDER_ALPHA, 1, R.string.sort_order_alpha)
- //.setIcon(android.R.drawable.ic_menu_sort_alphabetically)
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- menu.add(0, SORT_ORDER_SIZE, 2, R.string.sort_order_size)
- //.setIcon(android.R.drawable.ic_menu_sort_by_size)
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- menu.add(0, SHOW_RUNNING_SERVICES, 3, R.string.show_running_services)
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- menu.add(0, SHOW_BACKGROUND_PROCESSES, 3, R.string.show_background_processes)
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- menu.add(0, RESET_APP_PREFERENCES, 4, R.string.reset_app_preferences)
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- updateOptionsMenu();
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- updateOptionsMenu();
- }
-
- @Override
- public void onDestroyOptionsMenu() {
- mOptionsMenu = null;
- }
-
- @Override
- public void onDestroy() {
- getActivity().unbindService(mContainerConnection);
- super.onDestroy();
- }
-
- void updateOptionsMenu() {
- if (mOptionsMenu == null) {
- return;
- }
-
- /*
- * The running processes screen doesn't use the mApplicationsAdapter
- * so bringing up this menu in that case doesn't make any sense.
- */
- if (mCurTab != null && mCurTab.mListType == LIST_TYPE_RUNNING) {
- TabInfo tab = tabForType(LIST_TYPE_RUNNING);
- boolean showingBackground = tab != null && tab.mRunningProcessesView != null
- ? tab.mRunningProcessesView.mAdapter.getShowBackground() : false;
- mOptionsMenu.findItem(SORT_ORDER_ALPHA).setVisible(false);
- mOptionsMenu.findItem(SORT_ORDER_SIZE).setVisible(false);
- mOptionsMenu.findItem(SHOW_RUNNING_SERVICES).setVisible(showingBackground);
- mOptionsMenu.findItem(SHOW_BACKGROUND_PROCESSES).setVisible(!showingBackground);
- mOptionsMenu.findItem(RESET_APP_PREFERENCES).setVisible(false);
- mShowBackground = showingBackground;
- } else {
- mOptionsMenu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
- mOptionsMenu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder != SORT_ORDER_SIZE);
- mOptionsMenu.findItem(SHOW_RUNNING_SERVICES).setVisible(false);
- mOptionsMenu.findItem(SHOW_BACKGROUND_PROCESSES).setVisible(false);
- mOptionsMenu.findItem(RESET_APP_PREFERENCES).setVisible(true);
- }
- }
-
- void buildResetDialog() {
- if (mResetDialog == null) {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setTitle(R.string.reset_app_preferences_title);
- builder.setMessage(R.string.reset_app_preferences_desc);
- builder.setPositiveButton(R.string.reset_app_preferences_button, this);
- builder.setNegativeButton(R.string.cancel, null);
- mResetDialog = builder.show();
- mResetDialog.setOnDismissListener(this);
- }
- }
-
- @Override
- public void onDismiss(DialogInterface dialog) {
- if (mResetDialog == dialog) {
- mResetDialog = null;
- }
- }
-
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (mResetDialog == dialog) {
- final PackageManager pm = getActivity().getPackageManager();
- final IPackageManager mIPm = IPackageManager.Stub.asInterface(
- ServiceManager.getService("package"));
- final INotificationManager nm = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- final NetworkPolicyManager npm = NetworkPolicyManager.from(getActivity());
- final AppOpsManager aom = (AppOpsManager)getActivity().getSystemService(
- Context.APP_OPS_SERVICE);
- final Handler handler = new Handler(getActivity().getMainLooper());
- (new AsyncTask<Void, Void, Void>() {
- @Override protected Void doInBackground(Void... params) {
- List<ApplicationInfo> apps = pm.getInstalledApplications(
- PackageManager.GET_DISABLED_COMPONENTS);
- for (int i=0; i<apps.size(); i++) {
- ApplicationInfo app = apps.get(i);
- try {
- if (DEBUG) Log.v(TAG, "Enabling notifications: " + app.packageName);
- nm.setNotificationsEnabledForPackage(app.packageName, app.uid, true);
- } catch (android.os.RemoteException ex) {
- }
- if (!app.enabled) {
- if (DEBUG) Log.v(TAG, "Enabling app: " + app.packageName);
- if (pm.getApplicationEnabledSetting(app.packageName)
- == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
- pm.setApplicationEnabledSetting(app.packageName,
- PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
- PackageManager.DONT_KILL_APP);
- }
- }
- }
- try {
- mIPm.resetPreferredActivities(UserHandle.myUserId());
- } catch (RemoteException e) {
- }
- aom.resetAllModes();
- final int[] restrictedUids = npm.getUidsWithPolicy(
- POLICY_REJECT_METERED_BACKGROUND);
- final int currentUserId = ActivityManager.getCurrentUser();
- for (int uid : restrictedUids) {
- // Only reset for current user
- if (UserHandle.getUserId(uid) == currentUserId) {
- if (DEBUG) Log.v(TAG, "Clearing data policy: " + uid);
- npm.setUidPolicy(uid, POLICY_NONE);
- }
- }
- handler.post(new Runnable() {
- @Override public void run() {
- if (DEBUG) Log.v(TAG, "Done clearing");
- if (getActivity() != null && mActivityResumed) {
- if (DEBUG) Log.v(TAG, "Updating UI!");
- for (int i=0; i<mTabs.size(); i++) {
- TabInfo tab = mTabs.get(i);
- if (tab.mApplications != null) {
- tab.mApplications.pause();
- }
- }
- if (mCurTab != null) {
- mCurTab.resume(mSortOrder);
- }
- }
- }
- });
- return null;
- }
- }).execute();
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int menuId = item.getItemId();
- if ((menuId == SORT_ORDER_ALPHA) || (menuId == SORT_ORDER_SIZE)) {
- mSortOrder = menuId;
- if (mCurTab != null && mCurTab.mApplications != null) {
- mCurTab.mApplications.rebuild(mSortOrder);
- }
- } else if (menuId == SHOW_RUNNING_SERVICES) {
- mShowBackground = false;
- if (mCurTab != null && mCurTab.mRunningProcessesView != null) {
- mCurTab.mRunningProcessesView.mAdapter.setShowBackground(false);
- }
- } else if (menuId == SHOW_BACKGROUND_PROCESSES) {
- mShowBackground = true;
- if (mCurTab != null && mCurTab.mRunningProcessesView != null) {
- mCurTab.mRunningProcessesView.mAdapter.setShowBackground(true);
- }
- } else if (menuId == RESET_APP_PREFERENCES) {
- buildResetDialog();
- } else {
- // Handle the home button
- return false;
- }
- updateOptionsMenu();
- return true;
- }
-
- public void onItemClick(TabInfo tab, AdapterView<?> parent, View view, int position,
- long id) {
- if (tab.mApplications != null && tab.mApplications.getCount() > position) {
- ApplicationsState.AppEntry entry = tab.mApplications.getAppEntry(position);
- mCurrentPkgName = entry.info.packageName;
- mCurrentUid = entry.info.uid;
- startApplicationDetailsActivity();
- }
- }
-
- public void updateCurrentTab(int position) {
- TabInfo tab = mTabs.get(position);
- mCurTab = tab;
-
- // Put things in the correct paused/resumed state.
- if (mActivityResumed) {
- mCurTab.build(mInflater, mContentContainer, mRootView);
- mCurTab.resume(mSortOrder);
- } else {
- mCurTab.pause();
- }
- for (int i=0; i<mTabs.size(); i++) {
- TabInfo t = mTabs.get(i);
- if (t != mCurTab) {
- t.pause();
- }
- }
-
- mCurTab.updateStorageUsage();
- updateOptionsMenu();
- final Activity host = getActivity();
- if (host != null) {
- host.invalidateOptionsMenu();
- }
- }
-
- private volatile IMediaContainerService mContainerService;
-
- private final ServiceConnection mContainerConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- mContainerService = IMediaContainerService.Stub.asInterface(service);
- for (int i=0; i<mTabs.size(); i++) {
- mTabs.get(i).setContainerService(mContainerService);
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- mContainerService = null;
- }
- };
}