summaryrefslogtreecommitdiffstats
path: root/src/com/android/packageinstaller/permission/ui/handheld
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/packageinstaller/permission/ui/handheld')
-rw-r--r--src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java190
-rw-r--r--src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java107
-rw-r--r--src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java50
-rw-r--r--src/com/android/packageinstaller/permission/ui/handheld/ManageCustomPermissionsFragment.java46
-rw-r--r--src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java190
-rw-r--r--src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java107
-rw-r--r--src/com/android/packageinstaller/permission/ui/handheld/MultiTargetSwitchPreference.java59
-rw-r--r--src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java20
-rw-r--r--src/com/android/packageinstaller/permission/ui/handheld/RestrictedSwitchPreference.java2
9 files changed, 562 insertions, 209 deletions
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java
index 0c249e55..36570a54 100644
--- a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java
@@ -18,6 +18,7 @@ package com.android.packageinstaller.permission.ui.handheld;
import android.app.ActionBar;
import android.app.AlertDialog;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@@ -28,20 +29,27 @@ import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.preference.Preference;
-import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup;
import android.provider.Settings;
+import android.util.IconDrawableFactory;
import android.util.Log;
import android.view.MenuItem;
+import android.widget.Switch;
+
import com.android.packageinstaller.R;
+import com.android.packageinstaller.permission.model.AppPermissionGroup;
+import com.android.packageinstaller.permission.model.Permission;
+import com.android.packageinstaller.permission.utils.ArrayUtils;
import com.android.packageinstaller.permission.utils.Utils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.List;
public final class AllAppPermissionsFragment extends SettingsWithHeader {
@@ -49,10 +57,20 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader {
private static final String KEY_OTHER = "other_perms";
+ private static final String EXTRA_FILTER_GROUP =
+ "com.android.packageinstaller.extra.FILTER_GROUP";
+
+ private List<AppPermissionGroup> mGroups;
+
public static AllAppPermissionsFragment newInstance(String packageName) {
+ return newInstance(packageName, null);
+ }
+
+ public static AllAppPermissionsFragment newInstance(String packageName, String filterGroup) {
AllAppPermissionsFragment instance = new AllAppPermissionsFragment();
Bundle arguments = new Bundle();
arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
+ arguments.putString(EXTRA_FILTER_GROUP, filterGroup);
instance.setArguments(arguments);
return instance;
}
@@ -63,7 +81,12 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader {
setHasOptionsMenu(true);
final ActionBar ab = getActivity().getActionBar();
if (ab != null) {
- ab.setTitle(R.string.all_permissions);
+ // If we target a group make this look like app permissions.
+ if (getArguments().getString(EXTRA_FILTER_GROUP) == null) {
+ ab.setTitle(R.string.all_permissions);
+ } else {
+ ab.setTitle(R.string.app_permissions);
+ }
ab.setDisplayHomeAsUpEnabled(true);
}
}
@@ -94,6 +117,7 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader {
ArrayList<Preference> prefs = new ArrayList<>(); // Used for sorting.
prefs.add(otherGroup);
String pkg = getArguments().getString(Intent.EXTRA_PACKAGE_NAME);
+ String filterGroup = getArguments().getString(EXTRA_FILTER_GROUP);
otherGroup.removeAll();
PackageManager pm = getContext().getPackageManager();
@@ -101,7 +125,8 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader {
PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_PERMISSIONS);
ApplicationInfo appInfo = info.applicationInfo;
- final Drawable icon = appInfo.loadIcon(pm);
+ final Drawable icon =
+ IconDrawableFactory.newInstance(getContext()).getBadgedIcon(appInfo);
final CharSequence label = appInfo.loadLabel(pm);
Intent infoIntent = null;
if (!getActivity().getIntent().getBooleanExtra(
@@ -127,14 +152,41 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader {
continue;
}
- if (perm.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
- PermissionGroupInfo group = getGroup(perm.group, pm);
- PreferenceGroup pref =
- findOrCreate(group != null ? group : perm, pm, prefs);
- pref.addPreference(getPreference(perm, group, pm));
- } else if (perm.protectionLevel == PermissionInfo.PROTECTION_NORMAL) {
- PermissionGroupInfo group = getGroup(perm.group, pm);
- otherGroup.addPreference(getPreference(perm, group, pm));
+ if (appInfo.isInstantApp()
+ && (perm.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL)
+ == 0) {
+ continue;
+ }
+ if (appInfo.targetSdkVersion < Build.VERSION_CODES.M
+ && (perm.protectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY)
+ != 0) {
+ continue;
+ }
+
+ if ((perm.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+ == PermissionInfo.PROTECTION_DANGEROUS) {
+ PackageItemInfo group = getGroup(perm.group, pm);
+ if (group == null) {
+ group = perm;
+ }
+ // If we show a targeted group, then ignore everything else.
+ if (filterGroup != null && !group.name.equals(filterGroup)) {
+ continue;
+ }
+ PreferenceGroup pref = findOrCreate(group, pm, prefs);
+ pref.addPreference(getPreference(info, perm, group, pm));
+ } else if (filterGroup == null) {
+ if ((perm.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+ == PermissionInfo.PROTECTION_NORMAL) {
+ PermissionGroupInfo group = getGroup(perm.group, pm);
+ otherGroup.addPreference(getPreference(info,
+ perm, group, pm));
+ }
+ }
+
+ // If we show a targeted group, then don't show 'other' permissions.
+ if (filterGroup != null) {
+ getPreferenceScreen().removePreference(otherGroup);
}
}
}
@@ -184,9 +236,19 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader {
return pref;
}
- private Preference getPreference(PermissionInfo perm, PermissionGroupInfo group,
- PackageManager pm) {
- Preference pref = new Preference(getContext());
+ private Preference getPreference(PackageInfo packageInfo, PermissionInfo perm,
+ PackageItemInfo group, PackageManager pm) {
+ final Preference pref;
+
+ // We allow individual permission control for some permissions if review enabled
+ final boolean mutable = Utils.isPermissionIndividuallyControlled(getContext(), perm.name);
+ if (mutable) {
+ pref = new MyMultiTargetSwitchPreference(getContext(), perm.name,
+ getPermissionGroup(packageInfo, perm.name));
+ } else {
+ pref = new Preference(getContext());
+ }
+
Drawable icon = null;
if (perm.icon != 0) {
icon = perm.loadIcon(pm);
@@ -198,17 +260,97 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader {
pref.setIcon(Utils.applyTint(getContext(), icon, android.R.attr.colorControlNormal));
pref.setTitle(perm.loadLabel(pm));
final CharSequence desc = perm.loadDescription(pm);
- pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- new AlertDialog.Builder(getContext())
- .setMessage(desc)
- .setPositiveButton(android.R.string.ok, null)
- .show();
- return true;
- }
+
+ pref.setOnPreferenceClickListener((Preference preference) -> {
+ new AlertDialog.Builder(getContext())
+ .setMessage(desc)
+ .setPositiveButton(android.R.string.ok, null)
+ .show();
+ return mutable;
});
return pref;
}
-} \ No newline at end of file
+
+ private AppPermissionGroup getPermissionGroup(PackageInfo packageInfo,
+ String permission) {
+ AppPermissionGroup appPermissionGroup = null;
+ if (mGroups != null) {
+ final int groupCount = mGroups.size();
+ for (int i = 0; i < groupCount; i++) {
+ AppPermissionGroup currentPermissionGroup = mGroups.get(i);
+ if (currentPermissionGroup.hasPermission(permission)) {
+ appPermissionGroup = currentPermissionGroup;
+ break;
+ }
+ }
+ }
+ if (appPermissionGroup == null) {
+ appPermissionGroup = AppPermissionGroup.create(
+ getContext(), packageInfo, permission);
+ if (mGroups == null) {
+ mGroups = new ArrayList<>();
+ }
+ mGroups.add(appPermissionGroup);
+ }
+ return appPermissionGroup;
+ }
+
+ private static final class MyMultiTargetSwitchPreference extends MultiTargetSwitchPreference {
+ MyMultiTargetSwitchPreference(Context context, String permission,
+ AppPermissionGroup appPermissionGroup) {
+ super(context);
+
+ setChecked(appPermissionGroup.areRuntimePermissionsGranted(
+ new String[] {permission}));
+
+ setSwitchOnClickListener(v -> {
+ Switch switchView = (Switch) v;
+ if (switchView.isChecked()) {
+ appPermissionGroup.grantRuntimePermissions(false,
+ new String[]{permission});
+ // We are granting a permission from a group but since this is an
+ // individual permission control other permissions in the group may
+ // be revoked, hence we need to mark them user fixed to prevent the
+ // app from requesting a non-granted permission and it being granted
+ // because another permission in the group is granted. This applies
+ // only to apps that support runtime permissions.
+ if (appPermissionGroup.doesSupportRuntimePermissions()) {
+ int grantedCount = 0;
+ String[] revokedPermissionsToFix = null;
+ final int permissionCount = appPermissionGroup.getPermissions().size();
+ for (int i = 0; i < permissionCount; i++) {
+ Permission current = appPermissionGroup.getPermissions().get(i);
+ if (!current.isGranted()) {
+ if (!current.isUserFixed()) {
+ revokedPermissionsToFix = ArrayUtils.appendString(
+ revokedPermissionsToFix, current.getName());
+ }
+ } else {
+ grantedCount++;
+ }
+ }
+ if (revokedPermissionsToFix != null) {
+ // If some permissions were not granted then they should be fixed.
+ appPermissionGroup.revokeRuntimePermissions(true,
+ revokedPermissionsToFix);
+ } else if (appPermissionGroup.getPermissions().size() == grantedCount) {
+ // If all permissions are granted then they should not be fixed.
+ appPermissionGroup.grantRuntimePermissions(false);
+ }
+ }
+ } else {
+ appPermissionGroup.revokeRuntimePermissions(true,
+ new String[]{permission});
+ // If we just revoked the last permission we need to clear
+ // the user fixed state as now the app should be able to
+ // request them at runtime if supported.
+ if (appPermissionGroup.doesSupportRuntimePermissions()
+ && !appPermissionGroup.areRuntimePermissionsGranted()) {
+ appPermissionGroup.revokeRuntimePermissions(false);
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java
index c824325c..89869976 100644
--- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java
@@ -16,13 +16,14 @@
package com.android.packageinstaller.permission.ui.handheld;
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@@ -36,18 +37,19 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
import android.provider.Settings;
+import android.util.IconDrawableFactory;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
+import android.widget.Switch;
import android.widget.Toast;
+
import com.android.packageinstaller.R;
import com.android.packageinstaller.permission.model.AppPermissionGroup;
import com.android.packageinstaller.permission.model.AppPermissions;
+import com.android.packageinstaller.permission.model.Permission;
import com.android.packageinstaller.permission.utils.LocationUtils;
import com.android.packageinstaller.permission.utils.SafetyNetLogger;
import com.android.packageinstaller.permission.utils.Utils;
@@ -57,8 +59,6 @@ import com.android.settingslib.RestrictedLockUtils;
import java.util.ArrayList;
import java.util.List;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
public final class AppPermissionsFragment extends SettingsWithHeader
implements OnPreferenceChangeListener {
@@ -130,12 +130,7 @@ public final class AppPermissionsFragment extends SettingsWithHeader
}
case MENU_ALL_PERMS: {
- Fragment frag = AllAppPermissionsFragment.newInstance(
- getArguments().getString(Intent.EXTRA_PACKAGE_NAME));
- getFragmentManager().beginTransaction()
- .replace(android.R.id.content, frag)
- .addToBackStack("AllPerms")
- .commit();
+ showAllPermissions(null);
return true;
}
}
@@ -158,6 +153,16 @@ public final class AppPermissionsFragment extends SettingsWithHeader
getClass().getName());
}
+ private void showAllPermissions(String filterGroup) {
+ Fragment frag = AllAppPermissionsFragment.newInstance(
+ getArguments().getString(Intent.EXTRA_PACKAGE_NAME),
+ filterGroup);
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, frag)
+ .addToBackStack("AllPerms")
+ .commit();
+ }
+
private static void bindUi(SettingsWithHeader fragment, PackageInfo packageInfo) {
Activity activity = fragment.getActivity();
PackageManager pm = activity.getPackageManager();
@@ -168,7 +173,7 @@ public final class AppPermissionsFragment extends SettingsWithHeader
.setData(Uri.fromParts("package", packageInfo.packageName, null));
}
- Drawable icon = appInfo.loadIcon(pm);
+ Drawable icon = IconDrawableFactory.newInstance(activity).getBadgedIcon(appInfo);
CharSequence label = appInfo.loadLabel(pm);
fragment.setHeader(icon, label, infoIntent);
@@ -208,13 +213,36 @@ public final class AppPermissionsFragment extends SettingsWithHeader
boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG);
RestrictedSwitchPreference preference = new RestrictedSwitchPreference(context);
- preference.setOnPreferenceChangeListener(this);
+ preference.setChecked(group.areRuntimePermissionsGranted());
+
+ // Some groups may be a double target - one to toggle and one to fine manage
+ if (Utils.areGroupPermissionsIndividuallyControlled(getContext(), group.getName())) {
+ preference.setOnPreferenceClickListener((pref) -> {
+ showAllPermissions(group.getName());
+ return false;
+ });
+
+ preference.setSwitchOnClickListener(v -> {
+ Switch switchView = (Switch) v;
+ onPreferenceChange(preference, switchView.isChecked());
+ updateSummaryForIndividuallyControlledPermissionGroup(
+ group, preference);
+ preference.setCheckedOverride(switchView.isChecked());
+ });
+
+ updateSummaryForIndividuallyControlledPermissionGroup(group, preference);
+ } else {
+ preference.setOnPreferenceChangeListener(this);
+ }
+
preference.setKey(group.getName());
Drawable icon = Utils.loadDrawable(context.getPackageManager(),
group.getIconPkg(), group.getIconResId());
preference.setIcon(Utils.applyTint(getContext(), icon,
android.R.attr.colorControlNormal));
preference.setTitle(group.getLabel());
+
+
if (group.isPolicyFixed()) {
EnforcedAdmin admin = RestrictedLockUtils.getProfileOrDeviceOwner(getContext(),
group.getUserId());
@@ -227,7 +255,6 @@ public final class AppPermissionsFragment extends SettingsWithHeader
}
}
preference.setPersistent(false);
- preference.setChecked(group.areRuntimePermissionsGranted());
if (isPlatform) {
screen.addPreference(preference);
@@ -286,16 +313,22 @@ public final class AppPermissionsFragment extends SettingsWithHeader
new AlertDialog.Builder(getContext())
.setMessage(grantedByDefault ? R.string.system_warning
: R.string.old_sdk_deny_warning)
- .setNegativeButton(R.string.cancel, null)
+ .setNegativeButton(R.string.cancel, (DialogInterface dialog, int which) -> {
+ if (preference instanceof MultiTargetSwitchPreference) {
+ ((MultiTargetSwitchPreference) preference).setCheckedOverride(true);
+ }
+ })
.setPositiveButton(R.string.grant_dialog_button_deny_anyway,
- new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- ((SwitchPreference) preference).setChecked(false);
- group.revokeRuntimePermissions(false);
- if (!grantedByDefault) {
- mHasConfirmedRevoke = true;
- }
+ (DialogInterface dialog, int which) -> {
+ ((SwitchPreference) preference).setChecked(false);
+ group.revokeRuntimePermissions(false);
+ if (Utils.areGroupPermissionsIndividuallyControlled(getContext(),
+ group.getName())) {
+ updateSummaryForIndividuallyControlledPermissionGroup(
+ group, preference);
+ }
+ if (!grantedByDefault) {
+ mHasConfirmedRevoke = true;
}
})
.show();
@@ -314,6 +347,32 @@ public final class AppPermissionsFragment extends SettingsWithHeader
logToggledGroups();
}
+ private void updateSummaryForIndividuallyControlledPermissionGroup(
+ AppPermissionGroup group, Preference preference) {
+ int revokedCount = 0;
+ List<Permission> permissions = group.getPermissions();
+ final int permissionCount = permissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ Permission permission = permissions.get(i);
+ if (group.doesSupportRuntimePermissions()
+ ? !permission.isGranted() : !permission.isAppOpAllowed()) {
+ revokedCount++;
+ }
+ }
+
+ final int resId;
+ if (revokedCount == 0) {
+ resId = R.string.permission_revoked_none;
+ } else if (revokedCount == permissionCount) {
+ resId = R.string.permission_revoked_all;
+ } else {
+ resId = R.string.permission_revoked_count;
+ }
+
+ String summary = getString(resId, revokedCount);
+ preference.setSummary(summary);
+ }
+
private void addToggledGroup(AppPermissionGroup group) {
if (mToggledGroups == null) {
mToggledGroups = new ArrayList<>();
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java
index 6342826f..eec43b76 100644
--- a/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java
@@ -16,7 +16,8 @@
package com.android.packageinstaller.permission.ui.handheld;
-import android.content.Context;
+import android.app.Activity;
+import android.content.Intent;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -34,10 +35,11 @@ import android.widget.TextView;
import com.android.packageinstaller.R;
import com.android.packageinstaller.permission.ui.ButtonBarLayout;
import com.android.packageinstaller.permission.ui.GrantPermissionsViewHandler;
+import com.android.packageinstaller.permission.ui.ManagePermissionsActivity;
import com.android.packageinstaller.permission.ui.ManualLayoutFrame;
-public final class GrantPermissionsViewHandlerImpl
- implements GrantPermissionsViewHandler, OnClickListener {
+public class GrantPermissionsViewHandlerImpl implements GrantPermissionsViewHandler,
+ OnClickListener {
public static final String ARG_GROUP_NAME = "ARG_GROUP_NAME";
public static final String ARG_GROUP_COUNT = "ARG_GROUP_COUNT";
@@ -51,7 +53,9 @@ public final class GrantPermissionsViewHandlerImpl
private static final long OUT_DURATION = 200;
private static final long IN_DURATION = 300;
- private final Context mContext;
+ private final Activity mActivity;
+ private final String mAppPackageName;
+ private final boolean mPermissionReviewRequired;
private ResultListener mResultListener;
@@ -68,6 +72,7 @@ public final class GrantPermissionsViewHandlerImpl
private TextView mMessageView;
private CheckBox mDoNotAskCheckbox;
private Button mAllowButton;
+ private Button mMoreInfoButton;
private ManualLayoutFrame mRootView;
@@ -77,8 +82,10 @@ public final class GrantPermissionsViewHandlerImpl
private ViewGroup mDialogContainer;
private ButtonBarLayout mButtonBar;
- public GrantPermissionsViewHandlerImpl(Context context) {
- mContext = context;
+ public GrantPermissionsViewHandlerImpl(Activity activity, String appPackageName) {
+ mActivity = activity;
+ mAppPackageName = appPackageName;
+ mPermissionReviewRequired = activity.getPackageManager().isPermissionReviewModeEnabled();
}
@Override
@@ -140,7 +147,7 @@ public final class GrantPermissionsViewHandlerImpl
private void animateOldContent(Runnable callback) {
// Fade out old description group and scale out the icon for it.
- Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
+ Interpolator interpolator = AnimationUtils.loadInterpolator(mActivity,
android.R.interpolator.fast_out_linear_in);
// Icon scale to zero
@@ -170,7 +177,7 @@ public final class GrantPermissionsViewHandlerImpl
}
private void attachNewContent(final Runnable callback) {
- mCurrentDesc = (ViewGroup) LayoutInflater.from(mContext).inflate(
+ mCurrentDesc = (ViewGroup) LayoutInflater.from(mActivity).inflate(
R.layout.permission_description, mDescContainer, false);
mDescContainer.removeAllViews();
mDescContainer.addView(mCurrentDesc);
@@ -200,7 +207,7 @@ public final class GrantPermissionsViewHandlerImpl
mDescContainer.animate()
.translationY(0)
.scaleY(1.0f)
- .setInterpolator(AnimationUtils.loadInterpolator(mContext,
+ .setInterpolator(AnimationUtils.loadInterpolator(mActivity,
android.R.interpolator.linear_out_slow_in))
.setDuration(IN_DURATION)
.withEndAction(callback)
@@ -224,7 +231,7 @@ public final class GrantPermissionsViewHandlerImpl
}
private void animateNewContent() {
- Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
+ Interpolator interpolator = AnimationUtils.loadInterpolator(mActivity,
android.R.interpolator.linear_out_slow_in);
// Description slide in
@@ -265,7 +272,7 @@ public final class GrantPermissionsViewHandlerImpl
@Override
public View createView() {
- mRootView = (ManualLayoutFrame) LayoutInflater.from(mContext)
+ mRootView = (ManualLayoutFrame) LayoutInflater.from(mActivity)
.inflate(R.layout.grant_permissions, null);
mButtonBar = (ButtonBarLayout) mRootView.findViewById(R.id.button_group);
mButtonBar.setAllowStacking(true);
@@ -273,13 +280,20 @@ public final class GrantPermissionsViewHandlerImpl
mIconView = (ImageView) mRootView.findViewById(R.id.permission_icon);
mCurrentGroupView = (TextView) mRootView.findViewById(R.id.current_page_text);
mDoNotAskCheckbox = (CheckBox) mRootView.findViewById(R.id.do_not_ask_checkbox);
+
mAllowButton = (Button) mRootView.findViewById(R.id.permission_allow_button);
+ mAllowButton.setOnClickListener(this);
+
+ if (mPermissionReviewRequired) {
+ mMoreInfoButton = (Button) mRootView.findViewById(R.id.permission_more_info_button);
+ mMoreInfoButton.setVisibility(View.VISIBLE);
+ mMoreInfoButton.setOnClickListener(this);
+ }
mDialogContainer = (ViewGroup) mRootView.findViewById(R.id.dialog_container);
mDescContainer = (ViewGroup) mRootView.findViewById(R.id.desc_container);
mCurrentDesc = (ViewGroup) mRootView.findViewById(R.id.perm_desc_root);
- mAllowButton.setOnClickListener(this);
mRootView.findViewById(R.id.permission_deny_button).setOnClickListener(this);
mDoNotAskCheckbox.setOnClickListener(this);
@@ -298,17 +312,17 @@ public final class GrantPermissionsViewHandlerImpl
}
private void updateDescription() {
- mIconView.setImageDrawable(mGroupIcon.loadDrawable(mContext));
+ mIconView.setImageDrawable(mGroupIcon.loadDrawable(mActivity));
mMessageView.setText(mGroupMessage);
}
private void updateGroup() {
if (mGroupCount > 1) {
mCurrentGroupView.setVisibility(View.VISIBLE);
- mCurrentGroupView.setText(mContext.getString(R.string.current_permission_template,
+ mCurrentGroupView.setText(mActivity.getString(R.string.current_permission_template,
mGroupIndex + 1, mGroupCount));
} else {
- mCurrentGroupView.setVisibility(View.INVISIBLE);
+ mCurrentGroupView.setVisibility(View.GONE);
}
}
@@ -340,6 +354,12 @@ public final class GrantPermissionsViewHandlerImpl
mShowDonNotAsk && mDoNotAskCheckbox.isChecked());
}
break;
+ case R.id.permission_more_info_button:
+ Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS);
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppPackageName);
+ intent.putExtra(ManagePermissionsActivity.EXTRA_ALL_PERMISSIONS, true);
+ mActivity.startActivity(intent);
+ break;
case R.id.do_not_ask_checkbox:
mAllowButton.setEnabled(!mDoNotAskCheckbox.isChecked());
break;
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManageCustomPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManageCustomPermissionsFragment.java
new file mode 100644
index 00000000..4f740e2c
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/ui/handheld/ManageCustomPermissionsFragment.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller.permission.ui.handheld;
+
+import android.view.MenuItem;
+
+/**
+ * Fragment that allows the user to manage custom permissions.
+ */
+public class ManageCustomPermissionsFragment extends ManagePermissionsFragment {
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ getActivity().setTitle(com.android.packageinstaller.R.string.additional_permissions);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ getFragmentManager().popBackStack();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ protected void updatePermissionsUi() {
+ updatePermissionsUi(false);
+ }
+}
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java
index 238af36d..e50a1d89 100644
--- a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java
@@ -16,23 +16,16 @@
package com.android.packageinstaller.permission.ui.handheld;
import android.app.ActionBar;
-import android.app.FragmentTransaction;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.Preference;
-import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
import android.util.ArraySet;
import android.util.Log;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
+
import com.android.packageinstaller.R;
-import com.android.packageinstaller.permission.model.PermissionApps;
import com.android.packageinstaller.permission.model.PermissionApps.PmCache;
import com.android.packageinstaller.permission.model.PermissionGroup;
import com.android.packageinstaller.permission.model.PermissionGroups;
@@ -40,25 +33,20 @@ import com.android.packageinstaller.permission.utils.Utils;
import java.util.List;
-public final class ManagePermissionsFragment extends PermissionsFrameFragment
+/**
+ * Superclass for fragments allowing the user to manage permissions.
+ */
+abstract class ManagePermissionsFragment extends PermissionsFrameFragment
implements PermissionGroups.PermissionsGroupsChangeCallback,
Preference.OnPreferenceClickListener {
private static final String LOG_TAG = "ManagePermissionsFragment";
- private static final String OS_PKG = "android";
-
- private static final String EXTRA_PREFS_KEY = "extra_prefs_key";
+ static final String OS_PKG = "android";
private ArraySet<String> mLauncherPkgs;
private PermissionGroups mPermissions;
- private PreferenceScreen mExtraScreen;
-
- public static ManagePermissionsFragment newInstance() {
- return new ManagePermissionsFragment();
- }
-
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -69,23 +57,7 @@ public final class ManagePermissionsFragment extends PermissionsFrameFragment
ab.setDisplayHomeAsUpEnabled(true);
}
mLauncherPkgs = Utils.getLauncherPackages(getContext());
- mPermissions = new PermissionGroups(getActivity(), getLoaderManager(), this);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mPermissions.refresh();
- updatePermissionsUi();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == android.R.id.home) {
- getActivity().finish();
- return true;
- }
- return super.onOptionsItemSelected(item);
+ mPermissions = new PermissionGroups(getContext(), getLoaderManager(), this);
}
@Override
@@ -108,27 +80,34 @@ public final class ManagePermissionsFragment extends PermissionsFrameFragment
return true;
}
- @Override
- public void onPermissionGroupsChanged() {
- updatePermissionsUi();
+ /**
+ * @return the permissions
+ */
+ protected PermissionGroups getPermissions() {
+ return mPermissions;
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- bindPermissionUi(getActivity(), getView());
- }
-
- private static void bindPermissionUi(Context context, View rootView) {
- if (context == null || rootView == null) {
- return;
- }
+ public void onPermissionGroupsChanged() {
+ updatePermissionsUi();
}
- private void updatePermissionsUi() {
+ /**
+ * Update the preferences to show the new {@link #getPermissions() permissions}.
+ */
+ protected abstract void updatePermissionsUi();
+
+ /**
+ * Add preferences for all permissions of a type to the preference screen.
+ *
+ * @param addSystemPermissions If the permissions added should be system permissions or not
+ *
+ * @return The preference screen the permissions were added to
+ */
+ protected PreferenceScreen updatePermissionsUi(boolean addSystemPermissions) {
Context context = getActivity();
if (context == null) {
- return;
+ return null;
}
List<PermissionGroup> groups = mPermissions.getGroups();
@@ -136,6 +115,8 @@ public final class ManagePermissionsFragment extends PermissionsFrameFragment
if (screen == null) {
screen = getPreferenceManager().createPreferenceScreen(getActivity());
setPreferenceScreen(screen);
+ } else {
+ screen.removeAll();
}
// Use this to speed up getting the info for all of the PermissionApps below.
@@ -144,107 +125,30 @@ public final class ManagePermissionsFragment extends PermissionsFrameFragment
for (PermissionGroup group : groups) {
boolean isSystemPermission = group.getDeclaringPackage().equals(OS_PKG);
- Preference preference = findPreference(group.getName());
- if (preference == null && mExtraScreen != null) {
- preference = mExtraScreen.findPreference(group.getName());
- }
- if (preference == null) {
- preference = new Preference(context);
- preference.setOnPreferenceClickListener(this);
- preference.setKey(group.getName());
- preference.setIcon(Utils.applyTint(context, group.getIcon(),
- android.R.attr.colorControlNormal));
- preference.setTitle(group.getLabel());
- // Set blank summary so that no resizing/jumping happens when the summary is loaded.
- preference.setSummary(" ");
- preference.setPersistent(false);
- if (isSystemPermission) {
+ if (addSystemPermissions == isSystemPermission) {
+ Preference preference = findPreference(group.getName());
+
+ if (preference == null) {
+ preference = new Preference(context);
+ preference.setOnPreferenceClickListener(this);
+ preference.setKey(group.getName());
+ preference.setIcon(Utils.applyTint(context, group.getIcon(),
+ android.R.attr.colorControlNormal));
+ preference.setTitle(group.getLabel());
+ // Set blank summary so that no resizing/jumping happens when the summary is
+ // loaded.
+ preference.setSummary(" ");
+ preference.setPersistent(false);
screen.addPreference(preference);
- } else {
- if (mExtraScreen == null) {
- mExtraScreen = getPreferenceManager().createPreferenceScreen(context);
- }
- mExtraScreen.addPreference(preference);
}
+ preference.setSummary(getString(R.string.app_permissions_group_summary,
+ group.getGranted(), group.getTotal()));
}
- final Preference finalPref = preference;
-
- new PermissionApps(getContext(), group.getName(), new PermissionApps.Callback() {
- @Override
- public void onPermissionsLoaded(PermissionApps permissionApps) {
- if (getActivity() == null) {
- return;
- }
- int granted = permissionApps.getGrantedCount(mLauncherPkgs);
- int total = permissionApps.getTotalCount(mLauncherPkgs);
- finalPref.setSummary(getString(R.string.app_permissions_group_summary,
- granted, total));
- }
- }, cache).refresh(false);
- }
-
- if (mExtraScreen != null && mExtraScreen.getPreferenceCount() > 0
- && screen.findPreference(EXTRA_PREFS_KEY) == null) {
- Preference extraScreenPreference = new Preference(context);
- extraScreenPreference.setKey(EXTRA_PREFS_KEY);
- extraScreenPreference.setIcon(Utils.applyTint(context,
- R.drawable.ic_more_items,
- android.R.attr.colorControlNormal));
- extraScreenPreference.setTitle(R.string.additional_permissions);
- extraScreenPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- AdditionalPermissionsFragment frag = new AdditionalPermissionsFragment();
- frag.setTargetFragment(ManagePermissionsFragment.this, 0);
- FragmentTransaction ft = getFragmentManager().beginTransaction();
- ft.replace(android.R.id.content, frag);
- ft.addToBackStack(null);
- ft.commit();
- return true;
- }
- });
- int count = mExtraScreen.getPreferenceCount();
- extraScreenPreference.setSummary(getResources().getQuantityString(
- R.plurals.additional_permissions_more, count, count));
- screen.addPreference(extraScreenPreference);
}
if (screen.getPreferenceCount() != 0) {
setLoading(false /* loading */, true /* animate */);
}
- }
-
- public static class AdditionalPermissionsFragment extends PermissionsFrameFragment {
- @Override
- public void onCreate(Bundle icicle) {
- setLoading(true /* loading */, false /* animate */);
- super.onCreate(icicle);
- getActivity().setTitle(R.string.additional_permissions);
- setHasOptionsMenu(true);
- setPreferenceScreen(((ManagePermissionsFragment) getTargetFragment()).mExtraScreen);
- setLoading(false /* loading */, true /* animate */);
- }
-
- @Override
- public void onDestroy() {
- getActivity().setTitle(R.string.app_permissions);
- super.onDestroy();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- getFragmentManager().popBackStack();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- bindPermissionUi(getActivity(), getView());
- }
+ return screen;
}
}
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java
new file mode 100644
index 00000000..075ab3ce
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.packageinstaller.permission.ui.handheld;
+
+import android.app.FragmentTransaction;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.view.MenuItem;
+
+import com.android.packageinstaller.R;
+import com.android.packageinstaller.permission.model.PermissionGroup;
+import com.android.packageinstaller.permission.utils.Utils;
+
+import java.util.List;
+
+/**
+ * Fragment that allows the user to manage standard permissions.
+ */
+public final class ManageStandardPermissionsFragment extends ManagePermissionsFragment {
+ private static final String EXTRA_PREFS_KEY = "extra_prefs_key";
+
+ /**
+ * @return A new fragment
+ */
+ public static ManageStandardPermissionsFragment newInstance() {
+ return new ManageStandardPermissionsFragment();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ getActivity().setTitle(com.android.packageinstaller.R.string.app_permissions);
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ getActivity().finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ protected void updatePermissionsUi() {
+ PreferenceScreen screen = updatePermissionsUi(true);
+ if (screen == null) {
+ return;
+ }
+
+ // Check if we need an additional permissions preference
+ List<PermissionGroup> groups = getPermissions().getGroups();
+ int numExtraPermissions = 0;
+ for (PermissionGroup group : groups) {
+ if (!group.getDeclaringPackage().equals(ManagePermissionsFragment.OS_PKG)) {
+ numExtraPermissions++;
+ }
+ }
+
+ Preference additionalPermissionsPreference = screen.findPreference(EXTRA_PREFS_KEY);
+ if (numExtraPermissions == 0) {
+ if (additionalPermissionsPreference != null) {
+ screen.removePreference(additionalPermissionsPreference);
+ }
+ } else {
+ if (additionalPermissionsPreference == null) {
+ additionalPermissionsPreference = new Preference(getActivity());
+ additionalPermissionsPreference.setKey(EXTRA_PREFS_KEY);
+ additionalPermissionsPreference.setIcon(Utils.applyTint(getActivity(),
+ R.drawable.ic_more_items,
+ android.R.attr.colorControlNormal));
+ additionalPermissionsPreference.setTitle(R.string.additional_permissions);
+ additionalPermissionsPreference.setOnPreferenceClickListener(preference -> {
+ ManageCustomPermissionsFragment frag =
+ new ManageCustomPermissionsFragment();
+ frag.setTargetFragment(ManageStandardPermissionsFragment.this, 0);
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ ft.replace(android.R.id.content, frag);
+ ft.addToBackStack(null);
+ ft.commit();
+ return true;
+ });
+
+ screen.addPreference(additionalPermissionsPreference);
+ }
+
+ additionalPermissionsPreference.setSummary(getResources().getQuantityString(
+ R.plurals.additional_permissions_more, numExtraPermissions,
+ numExtraPermissions));
+ }
+ }
+}
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/MultiTargetSwitchPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/MultiTargetSwitchPreference.java
new file mode 100644
index 00000000..61e4fb9f
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/ui/handheld/MultiTargetSwitchPreference.java
@@ -0,0 +1,59 @@
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package com.android.packageinstaller.permission.ui.handheld;
+
+import android.content.Context;
+import android.preference.SwitchPreference;
+import android.view.View;
+import android.widget.Switch;
+
+class MultiTargetSwitchPreference extends SwitchPreference {
+ private View.OnClickListener mSwitchOnClickLister;
+
+ public MultiTargetSwitchPreference(Context context) {
+ super(context);
+ }
+
+ public void setCheckedOverride(boolean checked) {
+ super.setChecked(checked);
+ }
+
+ @Override
+ public void setChecked(boolean checked) {
+ // If double target behavior is enabled do nothing
+ if (mSwitchOnClickLister == null) {
+ super.setChecked(checked);
+ }
+ }
+
+ public void setSwitchOnClickListener(View.OnClickListener listener) {
+ mSwitchOnClickLister = listener;
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+ Switch switchView = (Switch) view.findViewById(
+ com.android.internal.R.id.switch_widget);
+ if (mSwitchOnClickLister != null) {
+ switchView.setOnClickListener(mSwitchOnClickLister);
+ final int padding = (int) ((view.getMeasuredHeight()
+ - switchView.getMeasuredHeight()) / 2 + 0.5f);
+ switchView.setPadding(padding, padding, 0, padding);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java
index 899c3c2c..f4dceb76 100644
--- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java
@@ -15,6 +15,8 @@
*/
package com.android.packageinstaller.permission.ui.handheld;
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.Fragment;
@@ -34,6 +36,7 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+
import com.android.packageinstaller.DeviceUtils;
import com.android.packageinstaller.R;
import com.android.packageinstaller.permission.model.AppPermissionGroup;
@@ -49,8 +52,6 @@ import com.android.settingslib.RestrictedLockUtils;
import java.util.ArrayList;
import java.util.List;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
public final class PermissionAppsFragment extends PermissionsFrameFragment implements Callback,
Preference.OnPreferenceChangeListener {
@@ -58,6 +59,9 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple
private static final int MENU_HIDE_SYSTEM = Menu.FIRST + 1;
private static final String KEY_SHOW_SYSTEM_PREFS = "_showSystem";
+ private static final String SHOW_SYSTEM_KEY = PermissionAppsFragment.class.getName()
+ + KEY_SHOW_SYSTEM_PREFS;
+
public static PermissionAppsFragment newInstance(String permissionName) {
return setPermissionName(new PermissionAppsFragment(), permissionName);
}
@@ -87,6 +91,11 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ if (savedInstanceState != null) {
+ mShowSystem = savedInstanceState.getBoolean(SHOW_SYSTEM_KEY);
+ }
+
setLoading(true /* loading */, false /* animate */);
setHasOptionsMenu(true);
final ActionBar ab = getActivity().getActionBar();
@@ -101,6 +110,13 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple
}
@Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putBoolean(SHOW_SYSTEM_KEY, mShowSystem);
+ }
+
+ @Override
public void onResume() {
super.onResume();
mPermissionApps.refresh(true);
diff --git a/src/com/android/packageinstaller/permission/ui/handheld/RestrictedSwitchPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/RestrictedSwitchPreference.java
index 44a7f471..a5dde173 100644
--- a/src/com/android/packageinstaller/permission/ui/handheld/RestrictedSwitchPreference.java
+++ b/src/com/android/packageinstaller/permission/ui/handheld/RestrictedSwitchPreference.java
@@ -28,7 +28,7 @@ import com.android.settingslib.RestrictedLockUtils;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-public class RestrictedSwitchPreference extends SwitchPreference {
+public class RestrictedSwitchPreference extends MultiTargetSwitchPreference {
private final Context mContext;
private boolean mDisabledByAdmin;
private EnforcedAdmin mEnforcedAdmin;