summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proguard.flags3
-rw-r--r--res/layout/preference_category_material.xml35
-rw-r--r--res/values/strings.xml5
-rwxr-xr-xres/values/styles.xml5
-rw-r--r--res/xml/all_permissions.xml24
-rw-r--r--src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java212
-rw-r--r--src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java20
7 files changed, 303 insertions, 1 deletions
diff --git a/proguard.flags b/proguard.flags
index f0a0f473..115958fa 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -2,4 +2,7 @@
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
+-keep class android.support.v7.preference.Preference* {
+ *;
+}
-dontwarn android.support.v4.**
diff --git a/res/layout/preference_category_material.xml b/res/layout/preference_category_material.xml
new file mode 100644
index 00000000..c60fd12b
--- /dev/null
+++ b/res/layout/preference_category_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<!-- Based on frameworks/base/core/res/res/layout/preference_category_material.xml
+ but has a ViewGroup at the root to make the support lib happy.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+android:id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dip"
+ android:textAppearance="@android:style/TextAppearance.Material.Body2"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:textColor="?android:attr/colorAccent"
+ android:paddingTop="16dip" />
+
+</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2e23df01..cbe193e2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -256,4 +256,9 @@
<!-- Text displayed until loading is done -->
<string name="loading">Loading\u2026</string>
+ <!-- [CHAR LIMIT=45] Title of all permissions settings -->
+ <string name="all_permissions">All permissions</string>
+ <!-- [CHAR LIMIT=45] Group of permissions granted to app automatically when installed. -->
+ <string name="other_permissions">Other app capabilities</string>
+
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e800b56f..6d772910 100755
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -29,6 +29,7 @@
<style name="PreferenceThemeOverlay.v14.Permissions">
<item name="preferenceStyle">@style/Preference.Permissions</item>
+ <item name="preferenceCategoryStyle">@style/Preference.Category.Permissions</item>
<item name="switchPreferenceStyle">@style/Preference.SwitchPreference.Permissions</item>
</style>
@@ -36,6 +37,10 @@
<item name="layout">@layout/preference_permissions</item>
</style>
+ <style name="Preference.Category.Permissions">
+ <item name="layout">@layout/preference_category_material</item>
+ </style>
+
<style name="Preference.SwitchPreference.Permissions">
<item name="layout">@layout/preference_permissions_switch</item>
</style>
diff --git a/res/xml/all_permissions.xml b/res/xml/all_permissions.xml
new file mode 100644
index 00000000..06e929fe
--- /dev/null
+++ b/res/xml/all_permissions.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/all_permissions">
+
+ <PreferenceCategory
+ android:key="other_perms"
+ android:title="@string/other_permissions" />
+
+</PreferenceScreen>
diff --git a/src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java
new file mode 100644
index 00000000..9e1c85e4
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/ui/AllAppPermissionsFragment.java
@@ -0,0 +1,212 @@
+/*
+* Copyright (C) 2015 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;
+
+import android.app.ActionBar;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceClickListener;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceGroup;
+import android.util.Log;
+import android.view.MenuItem;
+
+import com.android.packageinstaller.R;
+import com.android.packageinstaller.permission.utils.Utils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public final class AllAppPermissionsFragment extends SettingsWithHeader {
+
+ private static final String LOG_TAG = "AllAppPermissionsFragment";
+
+ private static final String KEY_OTHER = "other_perms";
+
+ public static AllAppPermissionsFragment newInstance(String packageName) {
+ AllAppPermissionsFragment instance = new AllAppPermissionsFragment();
+ Bundle arguments = new Bundle();
+ arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
+ instance.setArguments(arguments);
+ return instance;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ final ActionBar ab = getActivity().getActionBar();
+ if (ab != null) {
+ ab.setTitle(R.string.all_permissions);
+ ab.setDisplayHomeAsUpEnabled(true);
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateUi();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home: {
+ getFragmentManager().popBackStack();
+ return true;
+ }
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void updateUi() {
+ if (getPreferenceScreen() != null) {
+ getPreferenceScreen().removeAll();
+ }
+ addPreferencesFromResource(R.xml.all_permissions);
+ PreferenceGroup otherGroup = (PreferenceGroup) findPreference(KEY_OTHER);
+ ArrayList<Preference> prefs = new ArrayList<>(); // Used for sorting.
+ prefs.add(otherGroup);
+ String pkg = getArguments().getString(Intent.EXTRA_PACKAGE_NAME);
+ otherGroup.removeAll();
+ PackageManager pm = getContext().getPackageManager();
+
+ try {
+ PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_PERMISSIONS);
+
+ ApplicationInfo appInfo = info.applicationInfo;
+ final Drawable icon = appInfo.loadIcon(pm);
+ final CharSequence label = appInfo.loadLabel(pm);
+ Intent infoIntent = null;
+ if (!getActivity().getIntent().getBooleanExtra(
+ AppPermissionsFragment.EXTRA_HIDE_INFO_BUTTON, false)) {
+ infoIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ .setData(Uri.fromParts("package", pkg, null));
+ }
+ setHeader(icon, label, infoIntent);
+
+ if (info.requestedPermissions != null) {
+ for (int i = 0; i < info.requestedPermissions.length; i++) {
+ PermissionInfo perm;
+ try {
+ perm = pm.getPermissionInfo(info.requestedPermissions[i], 0);
+ } catch (NameNotFoundException e) {
+ Log.e(LOG_TAG,
+ "Can't get permission info for " + info.requestedPermissions[i], e);
+ 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));
+ }
+ }
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(LOG_TAG, "Problem getting package info for " + pkg, e);
+ }
+ // Sort an ArrayList of the groups and then set the order from the sorting.
+ Collections.sort(prefs, new Comparator<Preference>() {
+ @Override
+ public int compare(Preference lhs, Preference rhs) {
+ String lKey = lhs.getKey();
+ String rKey = rhs.getKey();
+ if (lKey.equals(KEY_OTHER)) {
+ return 1;
+ } else if (rKey.equals(KEY_OTHER)) {
+ return -1;
+ } else if (Utils.isModernPermissionGroup(lKey)
+ != Utils.isModernPermissionGroup(rKey)) {
+ return Utils.isModernPermissionGroup(lKey) ? -1 : 1;
+ }
+ return lhs.getTitle().toString().compareTo(rhs.getTitle().toString());
+ }
+ });
+ for (int i = 0; i < prefs.size(); i++) {
+ prefs.get(i).setOrder(i);
+ }
+ }
+
+ private PermissionGroupInfo getGroup(String group, PackageManager pm) {
+ try {
+ return pm.getPermissionGroupInfo(group, 0);
+ } catch (NameNotFoundException e) {
+ return null;
+ }
+ }
+
+ private PreferenceGroup findOrCreate(PackageItemInfo group, PackageManager pm,
+ ArrayList<Preference> prefs) {
+ PreferenceGroup pref = (PreferenceGroup) findPreference(group.name);
+ if (pref == null) {
+ pref = new PreferenceCategory(getContext());
+ pref.setKey(group.name);
+ pref.setLayoutResource(R.layout.preference_category_material);
+ pref.setTitle(group.loadLabel(pm));
+ prefs.add(pref);
+ getPreferenceScreen().addPreference(pref);
+ }
+ return pref;
+ }
+
+ private Preference getPreference(PermissionInfo perm, PermissionGroupInfo group,
+ PackageManager pm) {
+ Preference pref = new Preference(getContext());
+ pref.setLayoutResource(R.layout.preference_permissions);
+ Drawable icon = null;
+ if (perm.icon != 0) {
+ icon = perm.loadIcon(pm);
+ } else if (group != null && group.icon != 0) {
+ icon = group.loadIcon(pm);
+ } else {
+ icon = getContext().getDrawable(R.drawable.ic_perm_device_info);
+ }
+ 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;
+ }
+ });
+
+ return pref;
+ }
+} \ No newline at end of file
diff --git a/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java
index 52a2c8e1..93e263be 100644
--- a/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
+import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
@@ -62,7 +63,9 @@ public final class AppPermissionsFragment extends SettingsWithHeader
private static final String LOG_TAG = "ManagePermsFragment";
- private static final String EXTRA_HIDE_INFO_BUTTON = "hideInfoButton";
+ static final String EXTRA_HIDE_INFO_BUTTON = "hideInfoButton";
+
+ private static final int MENU_ALL_PERMS = 0;
private List<AppPermissionGroup> mToggledGroups;
private AppPermissions mAppPermissions;
@@ -94,6 +97,10 @@ public final class AppPermissionsFragment extends SettingsWithHeader
@Override
public void onResume() {
super.onResume();
+ final ActionBar ab = getActivity().getActionBar();
+ if (ab != null) {
+ ab.setTitle(R.string.app_permissions);
+ }
updateUi();
}
@@ -110,6 +117,16 @@ public final class AppPermissionsFragment extends SettingsWithHeader
bindPermissionsUi();
return true;
}
+
+ case MENU_ALL_PERMS: {
+ Fragment frag = AllAppPermissionsFragment.newInstance(
+ getArguments().getString(Intent.EXTRA_PACKAGE_NAME));
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ ft.replace(android.R.id.content, frag);
+ ft.addToBackStack("AllPerms");
+ ft.commit();
+ return true;
+ }
}
return super.onOptionsItemSelected(item);
}
@@ -124,6 +141,7 @@ public final class AppPermissionsFragment extends SettingsWithHeader
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.toggle_legacy_permissions, menu);
+ menu.add(Menu.NONE, MENU_ALL_PERMS, Menu.NONE, R.string.all_permissions);
}
@Override