diff options
Diffstat (limited to 'src/com')
3 files changed, 202 insertions, 31 deletions
diff --git a/src/com/android/settings/applications/AppOpsDetails.java b/src/com/android/settings/applications/AppOpsDetails.java index 13e4831..12da8b8 100644 --- a/src/com/android/settings/applications/AppOpsDetails.java +++ b/src/com/android/settings/applications/AppOpsDetails.java @@ -172,6 +172,8 @@ public class AppOpsDetails extends InstrumentedFragment { } ((TextView)view.findViewById(R.id.op_name)).setText( entry.getSwitchText(mState)); + ((TextView)view.findViewById(R.id.op_counts)).setText( + entry.getCountsText(res)); ((TextView)view.findViewById(R.id.op_time)).setText( entry.getTimeText(res, true)); diff --git a/src/com/android/settings/applications/AppOpsState.java b/src/com/android/settings/applications/AppOpsState.java index ae58ddd..e46d94a 100644 --- a/src/com/android/settings/applications/AppOpsState.java +++ b/src/com/android/settings/applications/AppOpsState.java @@ -16,6 +16,7 @@ package com.android.settings.applications; +import android.app.Activity; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -23,6 +24,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; +import android.content.SharedPreferences; import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; @@ -52,12 +54,15 @@ public class AppOpsState { List<AppOpEntry> mApps; + private SharedPreferences mPreferences; + public AppOpsState(Context context) { mContext = context; mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); mPm = context.getPackageManager(); mOpSummaries = context.getResources().getTextArray(R.array.app_ops_summaries_cm); mOpLabels = context.getResources().getTextArray(R.array.app_ops_labels_cm); + mPreferences = context.getSharedPreferences("appops_manager", Activity.MODE_PRIVATE); } public static class OpsTemplate implements Parcelable { @@ -383,30 +388,59 @@ public class AppOpsState { } private CharSequence getCombinedText(ArrayList<AppOpsManager.OpEntry> ops, - CharSequence[] items) { - if (ops.size() == 1) { - return items[ops.get(0).getOp()]; - } else { - StringBuilder builder = new StringBuilder(); - for (int i=0; i<ops.size(); i++) { - if (i > 0) { - builder.append(", "); - } - builder.append(items[ops.get(i).getOp()]); + CharSequence[] items, Resources res, boolean withTerseCounts) { + StringBuilder builder = new StringBuilder(); + for (int i=0; i<ops.size(); i++) { + if (i > 0) { + builder.append(", "); } - return builder.toString(); + AppOpsManager.OpEntry op = ops.get(i); + int count = op.getAllowedCount() + op.getIgnoredCount(); + + if (withTerseCounts && count > 0) { + String quantity = res.getQuantityString(R.plurals.app_ops_count, + count, count); + builder.append(res.getString(R.string.app_ops_entry_summary, + items[op.getOp()], quantity)); + } else { + builder.append(items[op.getOp()]); + } + } + return builder.toString(); + } + + public CharSequence getCountsText(Resources res) { + AppOpsManager.OpEntry op = mOps.get(0); + int allowed = op.getAllowedCount(); + int denied = op.getIgnoredCount(); + + if (allowed == 0 && denied == 0) { + return null; } + + CharSequence allowedQuantity = res.getQuantityString(R.plurals.app_ops_count, + allowed, allowed); + CharSequence deniedQuantity = res.getQuantityString(R.plurals.app_ops_count, + denied, denied); + + if (denied == 0) { + return res.getString(R.string.app_ops_allowed_count, allowedQuantity); + } else if (allowed == 0) { + return res.getString(R.string.app_ops_ignored_count, deniedQuantity); + } + return res.getString(R.string.app_ops_both_count, allowedQuantity, deniedQuantity); } public CharSequence getSummaryText(AppOpsState state) { - return getCombinedText(mOps, state.mOpSummaries); + return getCombinedText(mOps, state.mOpSummaries, state.mContext.getResources(), true); } public CharSequence getSwitchText(AppOpsState state) { + final Resources res = state.mContext.getResources(); if (mSwitchOps.size() > 0) { - return getCombinedText(mSwitchOps, state.mOpLabels); + return getCombinedText(mSwitchOps, state.mOpLabels, res, false); } else { - return getCombinedText(mOps, state.mOpLabels); + return getCombinedText(mOps, state.mOpLabels, res, false); } } @@ -490,19 +524,34 @@ public class AppOpsState { } private AppEntry getAppEntry(final Context context, final HashMap<String, AppEntry> appEntries, - final String packageName, ApplicationInfo appInfo) { + final String packageName, ApplicationInfo appInfo, boolean applyFilters) { + + if (appInfo == null) { + try { + appInfo = mPm.getApplicationInfo(packageName, + PackageManager.GET_DISABLED_COMPONENTS + | PackageManager.GET_UNINSTALLED_PACKAGES); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Unable to find info for package " + packageName); + return null; + } + } + + if (applyFilters) { + // Hide user apps if needed + if (!shouldShowUserApps() && + (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { + return null; + } + // Hide system apps if needed + if (!shouldShowSystemApps() && + (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + return null; + } + } + AppEntry appEntry = appEntries.get(packageName); if (appEntry == null) { - if (appInfo == null) { - try { - appInfo = mPm.getApplicationInfo(packageName, - PackageManager.GET_DISABLED_COMPONENTS - | PackageManager.GET_UNINSTALLED_PACKAGES); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Unable to find info for package " + packageName); - return null; - } - } appEntry = new AppEntry(this, appInfo); appEntry.loadLabel(context); appEntries.put(packageName, appEntry); @@ -510,6 +559,14 @@ public class AppOpsState { return appEntry; } + private boolean shouldShowUserApps() { + return mPreferences.getBoolean("show_user_apps", true); + } + + private boolean shouldShowSystemApps() { + return mPreferences.getBoolean("show_system_apps", true); + } + public List<AppOpEntry> buildState(OpsTemplate tpl, int uid, String packageName) { final Context context = mContext; @@ -530,6 +587,9 @@ public class AppOpsState { } } + // Whether to apply hide user / system app filters + final boolean applyFilters = (packageName == null); + List<AppOpsManager.PackageOps> pkgs; if (packageName != null) { pkgs = mAppOps.getOpsForPackage(uid, packageName, tpl.ops); @@ -540,7 +600,8 @@ public class AppOpsState { if (pkgs != null) { for (int i=0; i<pkgs.size(); i++) { AppOpsManager.PackageOps pkgOps = pkgs.get(i); - AppEntry appEntry = getAppEntry(context, appEntries, pkgOps.getPackageName(), null); + AppEntry appEntry = getAppEntry(context, appEntries, pkgOps.getPackageName(), null, + applyFilters); if (appEntry == null) { continue; } @@ -568,7 +629,7 @@ public class AppOpsState { for (int i=0; i<apps.size(); i++) { PackageInfo appInfo = apps.get(i); AppEntry appEntry = getAppEntry(context, appEntries, appInfo.packageName, - appInfo.applicationInfo); + appInfo.applicationInfo, applyFilters); if (appEntry == null) { continue; } @@ -602,7 +663,7 @@ public class AppOpsState { } AppOpsManager.OpEntry opEntry = new AppOpsManager.OpEntry( - permOps.get(k), AppOpsManager.MODE_ALLOWED, 0, 0, 0, -1, null); + permOps.get(k), AppOpsManager.MODE_ALLOWED, 0, 0, 0, -1, null, 0, 0); dummyOps.add(opEntry); addOp(entries, pkgOps, appEntry, opEntry, packageName == null, packageName == null ? 0 : opToOrder[opEntry.getOp()]); diff --git a/src/com/android/settings/applications/AppOpsSummary.java b/src/com/android/settings/applications/AppOpsSummary.java index 0d47dc1..71af7f4 100644 --- a/src/com/android/settings/applications/AppOpsSummary.java +++ b/src/com/android/settings/applications/AppOpsSummary.java @@ -16,10 +16,16 @@ package com.android.settings.applications; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.AppOpsManager; import android.app.Fragment; import android.app.FragmentManager; +import android.content.Context; +import android.content.DialogInterface; import android.content.res.Resources; import android.content.res.TypedArray; +import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceFrameLayout; import android.support.v13.app.FragmentPagerAdapter; @@ -27,6 +33,9 @@ import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; import android.util.TypedValue; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -42,6 +51,11 @@ public class AppOpsSummary extends InstrumentedFragment { private View mRootView; private ViewPager mViewPager; + private MyPagerAdapter mAdapter; + + private Activity mActivity; + private SharedPreferences mPreferences; + CharSequence[] mPageNames; static AppOpsState.OpsTemplate[] sPageTemplates = new AppOpsState.OpsTemplate[] { AppOpsState.LOCATION_TEMPLATE, @@ -88,6 +102,10 @@ public class AppOpsSummary extends InstrumentedFragment { mCurPos = position; } + public int getCurrentPage() { + return mCurPos; + } + @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_IDLE) { @@ -96,6 +114,14 @@ public class AppOpsSummary extends InstrumentedFragment { } } + private void resetAdapter() { + // trigger adapter load, preserving the selected page + int curPos = mAdapter.getCurrentPage(); + mViewPager.setAdapter(mAdapter); + mViewPager.setOnPageChangeListener(mAdapter); + mViewPager.setCurrentItem(curPos); + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // initialize the inflater @@ -109,9 +135,9 @@ public class AppOpsSummary extends InstrumentedFragment { mPageNames = getResources().getTextArray(R.array.app_ops_categories_cm); mViewPager = (ViewPager) rootView.findViewById(R.id.pager); - MyPagerAdapter adapter = new MyPagerAdapter(getChildFragmentManager()); - mViewPager.setAdapter(adapter); - mViewPager.setOnPageChangeListener(adapter); + mAdapter = new MyPagerAdapter(getChildFragmentManager()); + mViewPager.setAdapter(mAdapter); + mViewPager.setOnPageChangeListener(mAdapter); PagerTabStrip tabs = (PagerTabStrip) rootView.findViewById(R.id.tabs); Resources.Theme theme = tabs.getContext().getTheme(); @@ -126,6 +152,88 @@ public class AppOpsSummary extends InstrumentedFragment { ((PreferenceFrameLayout.LayoutParams) rootView.getLayoutParams()).removeBorders = true; } + mActivity = getActivity(); + return rootView; } + + private boolean shouldShowUserApps() { + return mPreferences.getBoolean("show_user_apps", true); + } + + private boolean shouldShowSystemApps() { + return mPreferences.getBoolean("show_system_apps", true); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + // get shared preferences + mPreferences = mActivity.getSharedPreferences("appops_manager", Activity.MODE_PRIVATE); + + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.appops_manager, menu); + menu.findItem(R.id.show_user_apps).setChecked(shouldShowUserApps()); + menu.findItem(R.id.show_system_apps).setChecked(shouldShowSystemApps()); + } + + private void resetCounters() { + final AppOpsManager appOps = + (AppOpsManager) mActivity.getSystemService(Context.APP_OPS_SERVICE); + if (appOps == null) { + return; + } + appOps.resetCounters(); + // reload content + resetAdapter(); + } + + private void resetCountersConfirm() { + new AlertDialog.Builder(getActivity()) + .setIcon(android.R.drawable.ic_dialog_alert) + .setTitle(R.string.app_ops_reset_confirm_title) + .setMessage(R.string.app_ops_reset_confirm_mesg) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialog, int which) { + resetCounters(); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.show_user_apps: + final String prefNameUserApps = "show_user_apps"; + // set the menu checkbox and save it in shared preference + item.setChecked(!item.isChecked()); + mPreferences.edit().putBoolean(prefNameUserApps, item.isChecked()).commit(); + // reload content + resetAdapter(); + return true; + case R.id.show_system_apps: + final String prefNameSysApps = "show_system_apps"; + // set the menu checkbox and save it in shared preference + item.setChecked(!item.isChecked()); + mPreferences.edit().putBoolean(prefNameSysApps, item.isChecked()).commit(); + // reload view content + resetAdapter(); + return true; + case R.id.reset_counters: + resetCountersConfirm(); + return true; + default: + return super.onContextItemSelected(item); + } + } } |