summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSvet Ganov <svetoslavganov@google.com>2015-05-04 11:10:02 -0700
committerSvet Ganov <svetoslavganov@google.com>2015-05-05 09:35:44 -0700
commita7a0406958991f7a964370295821d8e477f503e9 (patch)
tree56fc0376f80952a1434f72559613ab661dd60246
parent7b1843783d28e3a102cf6109841e5782d8afdf13 (diff)
downloadandroid_packages_apps_PackageInstaller-a7a0406958991f7a964370295821d8e477f503e9.tar.gz
android_packages_apps_PackageInstaller-a7a0406958991f7a964370295821d8e477f503e9.tar.bz2
android_packages_apps_PackageInstaller-a7a0406958991f7a964370295821d8e477f503e9.zip
Permission UI - legacy apps support - package installer
Change-Id: I23a7b4e42968df44d2dc3415bff2d15627653089
-rw-r--r--AndroidManifest.xml6
-rw-r--r--src/com/android/packageinstaller/permission/AppPermissions.java321
-rw-r--r--src/com/android/packageinstaller/permission/model/AppPermissions.java125
-rw-r--r--src/com/android/packageinstaller/permission/model/Permission.java57
-rw-r--r--src/com/android/packageinstaller/permission/model/PermissionApps.java (renamed from src/com/android/packageinstaller/permission/PermissionApps.java)186
-rw-r--r--src/com/android/packageinstaller/permission/model/PermissionGroup.java380
-rw-r--r--src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java (renamed from src/com/android/packageinstaller/permission/ManagePermissionsFragment.java)35
-rw-r--r--src/com/android/packageinstaller/permission/ui/GrantPermissionFragment.java (renamed from src/com/android/packageinstaller/permission/GrantPermissionFragment.java)6
-rw-r--r--src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java (renamed from src/com/android/packageinstaller/permission/GrantPermissionsActivity.java)14
-rw-r--r--src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java (renamed from src/com/android/packageinstaller/permission/ManagePermissionsActivity.java)6
-rw-r--r--src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java (renamed from src/com/android/packageinstaller/permission/PermissionManagementFragment.java)30
-rw-r--r--src/com/android/packageinstaller/permission/ui/SettingsWithHeader.java (renamed from src/com/android/packageinstaller/permission/SettingsWithHeader.java)2
-rw-r--r--src/com/android/packageinstaller/permission/utils/Utils.java39
13 files changed, 748 insertions, 459 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 705a6198..0e5b5306 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -14,6 +14,8 @@
<uses-permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.READ_INSTALL_SESSIONS" />
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+ <uses-permission android:name="android.permission.KILL_UID" />
<application android:label="@string/app_name"
android:allowBackup="false"
@@ -62,7 +64,7 @@
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="false" />
- <activity android:name=".permission.GrantPermissionsActivity"
+ <activity android:name=".permission.ui.GrantPermissionsActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="true"
android:theme="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
@@ -72,7 +74,7 @@
</intent-filter>
</activity>
- <activity android:name=".permission.ManagePermissionsActivity"
+ <activity android:name=".permission.ui.ManagePermissionsActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="true"
android:label="@string/app_permissions"
diff --git a/src/com/android/packageinstaller/permission/AppPermissions.java b/src/com/android/packageinstaller/permission/AppPermissions.java
deleted file mode 100644
index 47ec42f7..00000000
--- a/src/com/android/packageinstaller/permission/AppPermissions.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * 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;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PermissionGroupInfo;
-import android.content.pm.PermissionInfo;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.util.ArrayUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public final class AppPermissions {
- private static final String LOG_TAG = "AppPermissions";
-
- private final ArrayMap<String, PermissionGroup> mGroups = new ArrayMap<>();
-
- private final Context mContext;
-
- private final PackageInfo mPackageInfo;
-
- private final String[] mFilterPermissions;
-
- private final CharSequence mAppLabel;
-
- public AppPermissions(Context context, PackageInfo packageInfo, String[] permissions) {
- mContext = context;
- mPackageInfo = packageInfo;
- mFilterPermissions = permissions;
- mAppLabel = packageInfo.applicationInfo.loadLabel(context.getPackageManager());
- loadPermissionGroups();
- }
-
- public void refresh() {
- loadPermissionGroups();
- }
-
- public CharSequence getAppLabel() {
- return mAppLabel;
- }
-
- public PermissionGroup getPermissionGroup(String name) {
- return mGroups.get(name);
- }
-
- public List<PermissionGroup> getPermissionGroups() {
- return new ArrayList<>(mGroups.values());
- }
-
- private void loadPermissionGroups() {
- mGroups.clear();
- if (mPackageInfo.requestedPermissions == null) {
- return;
- }
-
- final boolean appSupportsRuntimePermissions = mPackageInfo.applicationInfo.targetSdkVersion
- > Build.VERSION_CODES.LOLLIPOP_MR1;
-
- for (int i = 0; i < mPackageInfo.requestedPermissions.length; i++) {
- String requestedPerm = mPackageInfo.requestedPermissions[i];
-
- final PermissionInfo permInfo;
- try {
- permInfo = mContext.getPackageManager().getPermissionInfo(requestedPerm, 0);
- } catch (NameNotFoundException e) {
- Log.w(LOG_TAG, "Unknown permission: " + requestedPerm);
- continue;
- }
-
- String permName = permInfo.name;
- String groupName = permInfo.group != null ? permInfo.group : permName;
-
- PermissionGroup group = mGroups.get(groupName);
- if (group == null) {
- PermissionGroupInfo groupInfo = null;
- if (permInfo.group != null) {
- try {
- groupInfo = mContext.getPackageManager().getPermissionGroupInfo(
- permInfo.group, 0);
- } catch (NameNotFoundException e) {
- Log.w(LOG_TAG, "Unknown group: " + permInfo.group);
- }
- }
-
- CharSequence groupLabel = (groupInfo != null)
- ? groupInfo.loadLabel(mContext.getPackageManager())
- : permInfo.loadLabel(mContext.getPackageManager());
-
- if (groupLabel == null) {
- Log.w(LOG_TAG, "Neither permission nor group have name."
- + " Ignoring permission: " + permInfo.name);
- continue;
- }
-
- final String iconPkg = (groupInfo != null)
- ? groupInfo.packageName : permInfo.packageName;
- final int iconResId = (groupInfo != null) ? groupInfo.icon : permInfo.icon;
-
- group = new PermissionGroup(mContext, mPackageInfo.packageName,
- groupName, groupLabel, iconPkg, iconResId);
- mGroups.put(groupName, group);
- }
-
- final boolean runtime = appSupportsRuntimePermissions
- && permInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
- final boolean granted = (mPackageInfo.requestedPermissionsFlags[i]
- & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
-
- Permission permission = new Permission(permName, runtime, granted);
- group.addPermission(permission);
- }
-
- if (ArrayUtils.isEmpty(mFilterPermissions)) {
- return;
- }
-
- final int groupCount = mGroups.size();
- for (int i = groupCount - 1; i >= 0; i--) {
- PermissionGroup group = mGroups.valueAt(i);
- boolean groupHasPermission = false;
- for (String filterPerm : mFilterPermissions) {
- if (group.mPermissions.containsKey(filterPerm)) {
- groupHasPermission = true;
- break;
- }
- }
- if (!groupHasPermission) {
- mGroups.removeAt(i);
- }
- }
- }
-
- public static final class PermissionGroup {
- private final Context mContext;
- private final String mPackageName;
-
- private final String mName;
- private final CharSequence mLabel;
- private final ArrayMap<String, Permission> mPermissions = new ArrayMap<>();
- private final String mIconPkg;
- private final int mIconResId;
-
- private boolean mHasRuntimePermissions;
-
- public String getName() {
- return mName;
- }
-
- public String getIconPkg() {
- return mIconPkg;
- }
-
- public int getIconResId() {
- return mIconResId;
- }
-
- public CharSequence getLabel() {
- return mLabel;
- }
-
- public PermissionGroup(Context context, String packageName,
- String name, CharSequence label, String iconPkg, int iconResId) {
- mPackageName = packageName;
- mContext = context;
- mName = name;
- mLabel = label;
- mIconPkg = iconPkg;
- mIconResId = iconResId;
- }
-
- public boolean hasRuntimePermissions() {
- return mHasRuntimePermissions;
- }
-
- public boolean areRuntimePermissionsGranted() {
- final int permissionCount = mPermissions.size();
- for (int i = 0; i < permissionCount; i++) {
- Permission permission = mPermissions.valueAt(i);
- if (permission.mRuntime && !permission.mGranted) {
- return false;
- }
- }
- return true;
- }
-
- public boolean grantRuntimePermissions() {
- for (Permission permission : mPermissions.values()) {
- if (permission.mRuntime && !permission.mGranted) {
- mContext.getPackageManager().grantPermission(mPackageName,
- permission.mName, new UserHandle(mContext.getUserId()));
- permission.mGranted = true;
- }
- }
- return true;
- }
-
- public boolean revokeRuntimePermissions() {
- for (Permission permission : mPermissions.values()) {
- if (permission.mRuntime && permission.mGranted) {
- mContext.getPackageManager().revokePermission(mPackageName,
- permission.mName, new UserHandle(mContext.getUserId()));
- permission.mGranted = false;
- }
- }
- return true;
- }
-
- public List<Permission> getPermissions() {
- return new ArrayList<>(mPermissions.values());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj == null) {
- return false;
- }
-
- if (getClass() != obj.getClass()) {
- return false;
- }
-
- PermissionGroup other = (PermissionGroup) obj;
-
- if (mName == null) {
- if (other.mName != null) {
- return false;
- }
- } else if (!mName.equals(other.mName)) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return mName != null ? mName.hashCode() : 0;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append(getClass().getSimpleName());
- builder.append("{name=").append(mName);
- if (!mPermissions.isEmpty()) {
- builder.append(", <has permissions>}");
- } else {
- builder.append('}');
- }
- return builder.toString();
- }
-
- void addPermission(Permission permission) {
- mPermissions.put(permission.mName, permission);
- if (permission.mRuntime) {
- mHasRuntimePermissions = true;
- }
- }
- }
-
- public static final class Permission {
- private final String mName;
- private final boolean mRuntime;
- private boolean mGranted;
-
- public Permission(String name, boolean runtime, boolean granted) {
- mName = name;
- mRuntime = runtime;
- mGranted = granted;
- }
-
- public String getName() {
- return mName;
- }
-
- public boolean isGranted() {
- return mGranted;
- }
-
- public void setGranted(boolean granted) {
- mGranted = granted;
- }
- }
-
- public static Drawable loadDrawable(PackageManager pm, String pkg, int resId) {
- try {
- return pm.getResourcesForApplication(pkg).getDrawable(resId, null);
- } catch (NotFoundException | NameNotFoundException e) {
- Log.d(LOG_TAG, "Couldn't get resource", e);
- return null;
- }
- }
-}
diff --git a/src/com/android/packageinstaller/permission/model/AppPermissions.java b/src/com/android/packageinstaller/permission/model/AppPermissions.java
new file mode 100644
index 00000000..9480ce90
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/model/AppPermissions.java
@@ -0,0 +1,125 @@
+/*
+ * 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.model;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.util.ArrayMap;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public final class AppPermissions {
+ private final ArrayMap<String, PermissionGroup> mGroups = new ArrayMap<>();
+
+ private final Context mContext;
+
+ private final PackageInfo mPackageInfo;
+
+ private final String[] mFilterPermissions;
+
+ private final CharSequence mAppLabel;
+
+ public AppPermissions(Context context, PackageInfo packageInfo, String[] permissions) {
+ mContext = context;
+ mPackageInfo = packageInfo;
+ mFilterPermissions = permissions;
+ mAppLabel = packageInfo.applicationInfo.loadLabel(context.getPackageManager());
+ loadPermissionGroups();
+ }
+
+ public PackageInfo getPackageInfo() {
+ return mPackageInfo;
+ }
+
+ public void refresh() {
+ loadPermissionGroups();
+ }
+
+ public CharSequence getAppLabel() {
+ return mAppLabel;
+ }
+
+ public PermissionGroup getPermissionGroup(String name) {
+ return mGroups.get(name);
+ }
+
+ public List<PermissionGroup> getPermissionGroups() {
+ return new ArrayList<>(mGroups.values());
+ }
+
+ private void loadPermissionGroups() {
+ List<PermissionGroup> groups = new ArrayList<>();
+
+ if (mPackageInfo.requestedPermissions == null) {
+ return;
+ }
+
+ for (int i = 0; i < mPackageInfo.requestedPermissions.length; i++) {
+ String requestedPerm = mPackageInfo.requestedPermissions[i];
+
+ if (hasGroupForPermission(requestedPerm, groups)) {
+ continue;
+ }
+
+ PermissionGroup group = PermissionGroup.create(mContext,
+ mPackageInfo, requestedPerm);
+ if (group == null) {
+ continue;
+ }
+
+ groups.add(group);
+ }
+
+ if (!ArrayUtils.isEmpty(mFilterPermissions)) {
+ final int groupCount = groups.size();
+ for (int i = groupCount - 1; i >= 0; i--) {
+ PermissionGroup group = groups.get(i);
+ boolean groupHasPermission = false;
+ for (String filterPerm : mFilterPermissions) {
+ if (group.hasPermission(filterPerm)) {
+ groupHasPermission = true;
+ break;
+ }
+ }
+ if (!groupHasPermission) {
+ groups.remove(i);
+ }
+ }
+ }
+
+ Collections.sort(groups);
+
+ mGroups.clear();
+ for (PermissionGroup group : groups) {
+ mGroups.put(group.getName(), group);
+ }
+ }
+
+ private static boolean hasGroupForPermission(String permission,
+ List<PermissionGroup> groups) {
+ for (PermissionGroup group : groups) {
+ if (group.hasPermission(permission)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/packageinstaller/permission/model/Permission.java b/src/com/android/packageinstaller/permission/model/Permission.java
new file mode 100644
index 00000000..1f51fea9
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/model/Permission.java
@@ -0,0 +1,57 @@
+/*
+ * 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.model;
+
+public final class Permission {
+ private final String mName;
+ private final int mAppOp;
+
+ private boolean mGranted;
+ private boolean mAppOpAllowed;
+
+ public Permission(String name, boolean granted,
+ int appOp, boolean appOpAllowed) {
+ mName = name;
+ mGranted = granted;
+ mAppOp = appOp;
+ mAppOpAllowed = appOpAllowed;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public int getAppOp() {
+ return mAppOp;
+ }
+
+ public boolean isGranted() {
+ return mGranted;
+ }
+
+ public void setGranted(boolean mGranted) {
+ this.mGranted = mGranted;
+ }
+
+ public boolean isAppOpAllowed() {
+ return mAppOpAllowed;
+ }
+
+ public void setAppOpAllowed(boolean mAppOpAllowed) {
+ this.mAppOpAllowed = mAppOpAllowed;
+ }
+} \ No newline at end of file
diff --git a/src/com/android/packageinstaller/permission/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java
index b441d613..8f28433b 100644
--- a/src/com/android/packageinstaller/permission/PermissionApps.java
+++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.packageinstaller.permission;
+package com.android.packageinstaller.permission.model;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -21,27 +21,22 @@ 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.LightingColorFilter;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.os.Build;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
import android.util.Log;
-import com.android.packageinstaller.permission.AppPermissions.Permission;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class PermissionApps {
-
- private static final String LOG_TAG = "PermissionGroup";
+ private static final String LOG_TAG = "PermissionApps";
private final Context mContext;
private final String mGroupName;
@@ -50,7 +45,7 @@ public class PermissionApps {
private CharSequence mLabel;
private Drawable mIcon;
- private ArrayList<PermissionApp> mAppPerms;
+ private List<PermissionApp> mPermApps;
// Map (pkg|uid) -> AppPermission
private ArrayMap<String, PermissionApp> mAppLookup;
@@ -68,7 +63,7 @@ public class PermissionApps {
}
public Collection<PermissionApp> getApps() {
- return mAppPerms;
+ return mPermApps;
}
public PermissionApp getApp(String key) {
@@ -84,10 +79,10 @@ public class PermissionApps {
}
private void loadGroupInfo() {
- PackageItemInfo info = null;
+ PackageItemInfo info;
try {
info = mPm.getPermissionGroupInfo(mGroupName, 0);
- } catch (NameNotFoundException e) {
+ } catch (PackageManager.NameNotFoundException e) {
try {
PermissionInfo permInfo = mPm.getPermissionInfo(mGroupName, 0);
if (permInfo.protectionLevel != PermissionInfo.PROTECTION_DANGEROUS) {
@@ -107,25 +102,19 @@ public class PermissionApps {
}
public static class PermissionApp implements Comparable<PermissionApp> {
- private final Context mContext;
+ private final PermissionGroup mPermissionGroup;
private final String mLabel;
private final Drawable mIcon;
- private final String mPkg;
- private final int mUid;
- private final List<Permission> mPermissions = new ArrayList<>();
- private boolean mHasPermission;
- public PermissionApp(Context context, String pkg, int uid, String label,
+ public PermissionApp(PermissionGroup permissionGroup, String label,
Drawable icon) {
- mContext = context;
- mPkg = pkg;
- mUid = uid;
+ mPermissionGroup = permissionGroup;
mLabel = label;
mIcon = icon;
}
public String getKey() {
- return Integer.toString(mUid);
+ return Integer.toString(getUid());
}
public String getLabel() {
@@ -136,104 +125,122 @@ public class PermissionApps {
return mIcon;
}
- public boolean hasRuntimePermissions() {
- return mHasPermission;
+ public boolean areRuntimePermissionsGranted() {
+ return mPermissionGroup.areRuntimePermissionsGranted();
}
- /**
- * Note: This class only expects to have runtime permissions added.
- */
- public void addPermission(Permission permission) {
- mPermissions.add(permission);
- if (permission.isGranted()) {
- mHasPermission = true;
- }
+ public void grantRuntimePermissions() {
+ mPermissionGroup.grantRuntimePermissions();
}
- public boolean grantRuntimePermissions() {
- for (Permission permission : mPermissions) {
- if (!permission.isGranted()) {
- mContext.getPackageManager().grantPermission(mPkg,
- permission.getName(), new UserHandle(UserHandle.getUserId(mUid)));
- permission.setGranted(true);
- }
- }
- return true;
- }
-
- public boolean revokeRuntimePermissions() {
- for (Permission permission : mPermissions) {
- if (permission.isGranted()) {
- mContext.getPackageManager().revokePermission(mPkg,
- permission.getName(), new UserHandle(UserHandle.getUserId(mUid)));
- permission.setGranted(false);
- }
- }
- return true;
+ public void revokeRuntimePermissions() {
+ mPermissionGroup.revokeRuntimePermissions();
}
@Override
public int compareTo(PermissionApp another) {
- int result = mLabel.compareTo(another.mLabel);
+ final int result = mLabel.compareTo(another.mLabel);
if (result == 0) {
// Unbadged before badged.
- return mUid - another.mUid;
+ return getUid() - another.getUid();
}
return result;
}
+ private int getUid() {
+ return mPermissionGroup.getApp().applicationInfo.uid;
+ }
}
- private class PermissionAppsLoader extends AsyncTask<Void, Void, ArrayList<PermissionApp>> {
-
+ private class PermissionAppsLoader extends AsyncTask<Void, Void, List<PermissionApp>> {
@Override
- protected ArrayList<PermissionApp> doInBackground(Void... params) {
- ArrayList<String> permStrs = new ArrayList<>();
- try {
- List<PermissionInfo> permissions = mPm.queryPermissionsByGroup(mGroupName, 0);
- for (PermissionInfo info : permissions) {
- if (info.protectionLevel != PermissionInfo.PROTECTION_DANGEROUS) {
- continue;
- }
- permStrs.add(info.name);
- }
- } catch (NameNotFoundException e) {
- permStrs.add(mGroupName);
+ protected List<PermissionApp> doInBackground(Void... args) {
+ PackageItemInfo groupInfo = getGroupInfo(mGroupName);
+ if (groupInfo == null) {
+ return Collections.emptyList();
}
- ArrayList<PermissionApp> appPerms = new ArrayList<>();
+
+ List<PermissionInfo> groupPermInfos = getGroupPermissionInfos(mGroupName);
+ if (groupPermInfos == null) {
+ return Collections.emptyList();
+ }
+
+ ArrayList<PermissionApp> permApps = new ArrayList<>();
+
for (UserHandle user : UserManager.get(mContext).getUserProfiles()) {
List<PackageInfo> apps = mPm.getInstalledPackages(
PackageManager.GET_PERMISSIONS, user.getIdentifier());
+
final int N = apps.size();
for (int i = 0; i < N; i++) {
PackageInfo app = apps.get(i);
- if (app.applicationInfo.targetSdkVersion
- <= Build.VERSION_CODES.LOLLIPOP_MR1) {
- // Only care about apps that support runtime permissions here.
- continue;
- }
if (app.requestedPermissions == null) {
continue;
}
- PermissionApp appPermission = new PermissionApp(mContext,
- app.packageName, app.applicationInfo.uid,
- app.applicationInfo.loadLabel(mPm).toString(),
- getBadgedIcon(app.applicationInfo));
+
for (int j = 0; j < app.requestedPermissions.length; j++) {
- if (permStrs.contains(app.requestedPermissions[j])) {
- boolean granted = (app.requestedPermissionsFlags[j]
- & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
- appPermission.addPermission(new Permission(
- app.requestedPermissions[j], true, granted));
+ String requestedPerm = app.requestedPermissions[j];
+
+ boolean requestsPermissionInGroup = false;
+
+ for (PermissionInfo groupPermInfo : groupPermInfos) {
+ if (groupPermInfo.name.equals(requestedPerm)) {
+ requestsPermissionInGroup = true;
+ break;
+ }
}
- }
- if (appPermission.mPermissions.size() != 0) {
- appPerms.add(appPermission);
+
+ if (!requestsPermissionInGroup) {
+ continue;
+ }
+
+ PermissionGroup group = PermissionGroup.create(mContext,
+ app, groupInfo, groupPermInfos);
+
+ PermissionApp permApp = new PermissionApp(group,
+ app.applicationInfo.loadLabel(mPm).toString(),
+ getBadgedIcon(app.applicationInfo));
+
+ permApps.add(permApp);
}
}
}
- Collections.sort(appPerms);
- return appPerms;
+
+ Collections.sort(permApps);
+
+ return permApps;
+ }
+
+ private PackageItemInfo getGroupInfo(String groupName) {
+ try {
+ return mContext.getPackageManager().getPermissionGroupInfo(groupName, 0);
+ } catch (NameNotFoundException e) {
+ /* ignore */
+ }
+ try {
+ return mContext.getPackageManager().getPermissionInfo(groupName, 0);
+ } catch (NameNotFoundException e2) {
+ /* ignore */
+ }
+ return null;
+ }
+
+ private List<PermissionInfo> getGroupPermissionInfos(String groupName) {
+ try {
+ return mContext.getPackageManager().queryPermissionsByGroup(groupName, 0);
+ } catch (NameNotFoundException e) {
+ /* ignore */
+ }
+ try {
+ PermissionInfo permissionInfo = mContext.getPackageManager()
+ .getPermissionInfo(groupName, 0);
+ List<PermissionInfo> permissions = new ArrayList<>();
+ permissions.add(permissionInfo);
+ return permissions;
+ } catch (NameNotFoundException e2) {
+ /* ignore */
+ }
+ return null;
}
private Drawable getBadgedIcon(ApplicationInfo appInfo) {
@@ -243,12 +250,12 @@ public class PermissionApps {
}
@Override
- protected void onPostExecute(ArrayList<PermissionApp> result) {
+ protected void onPostExecute(List<PermissionApp> result) {
mAppLookup = new ArrayMap<>();
for (PermissionApp app : result) {
mAppLookup.put(app.getKey(), app);
}
- mAppPerms = result;
+ mPermApps = result;
mCallback.onPermissionsLoaded();
}
}
@@ -256,5 +263,4 @@ public class PermissionApps {
public interface Callback {
void onPermissionsLoaded();
}
-
}
diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroup.java b/src/com/android/packageinstaller/permission/model/PermissionGroup.java
new file mode 100644
index 00000000..9a5291d8
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/model/PermissionGroup.java
@@ -0,0 +1,380 @@
+/*
+ * 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.model;
+
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.os.Build;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class PermissionGroup implements Comparable<PermissionGroup> {
+ private static final String PLATFORM_PACKAGE_NAME = "android";
+
+ private static final String KILL_REASON_APP_OP_CHANGE = "Permission related app op changed";
+
+ private final Context mContext;
+ private final AppOpsManager mAppOps;
+ private final ActivityManager mActivityManager;
+
+ private final PackageInfo mPackageInfo;
+ private final String mName;
+ private final CharSequence mLabel;
+ private final ArrayMap<String, Permission> mPermissions = new ArrayMap<>();
+ private final String mIconPkg;
+ private final int mIconResId;
+
+ private final boolean mAppSupportsRuntimePermissions;
+
+ public static PermissionGroup create(Context context, PackageInfo packageInfo,
+ String permissionName) {
+ PermissionInfo permissionInfo;
+ try {
+ permissionInfo = context.getPackageManager().getPermissionInfo(permissionName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ return null;
+ }
+
+ if (permissionInfo.protectionLevel != PermissionInfo.PROTECTION_DANGEROUS) {
+ return null;
+ }
+
+ PackageItemInfo groupInfo = permissionInfo;
+ if (permissionInfo.group != null) {
+ try {
+ groupInfo = context.getPackageManager().getPermissionGroupInfo(
+ permissionInfo.group, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ /* ignore */
+ }
+ }
+
+ List<PermissionInfo> permissionInfos = null;
+ if (groupInfo instanceof PermissionGroupInfo) {
+ try {
+ permissionInfos = context.getPackageManager().queryPermissionsByGroup(
+ groupInfo.name, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ /* ignore */
+ }
+ }
+
+ return create(context, packageInfo, groupInfo, permissionInfos);
+
+ }
+
+ public static PermissionGroup create(Context context, PackageInfo packageInfo,
+ PackageItemInfo groupInfo, List<PermissionInfo> permissionInfos) {
+
+ PermissionGroup group = new PermissionGroup(context, packageInfo, groupInfo.name,
+ groupInfo.loadLabel(context.getPackageManager()), groupInfo.packageName,
+ groupInfo.icon);
+
+ if (groupInfo instanceof PermissionInfo) {
+ permissionInfos = new ArrayList<>();
+ permissionInfos.add((PermissionInfo) groupInfo);
+ }
+
+ if (permissionInfos == null || permissionInfos.isEmpty()) {
+ return null;
+ }
+
+ final int permissionCount = packageInfo.requestedPermissions.length;
+ for (int i = 0; i < permissionCount; i++) {
+ String requestedPermission = packageInfo.requestedPermissions[i];
+
+ PermissionInfo requestedPermissionInfo = null;
+
+ for (PermissionInfo permissionInfo : permissionInfos) {
+ if (requestedPermission.equals(permissionInfo.name)) {
+ requestedPermissionInfo = permissionInfo;
+ break;
+ }
+ }
+
+ if (requestedPermissionInfo == null) {
+ continue;
+ }
+
+ // Collect only runtime permissions.
+ if (requestedPermissionInfo.protectionLevel != PermissionInfo.PROTECTION_DANGEROUS) {
+ continue;
+ }
+
+ // Don't allow toggle of non platform defined permissions for legacy apps via app ops.
+ if (packageInfo.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1
+ && !PLATFORM_PACKAGE_NAME.equals(requestedPermissionInfo.packageName)) {
+ continue;
+ }
+
+
+ final boolean granted = (packageInfo.requestedPermissionsFlags[i]
+ & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
+
+ final int appOp;
+ final boolean appOpAllowed;
+
+ if (group.mAppSupportsRuntimePermissions) {
+ appOp = AppOpsManager.OP_NONE;
+ appOpAllowed = false;
+ } else {
+ appOp = PLATFORM_PACKAGE_NAME.equals(requestedPermissionInfo.packageName)
+ ? AppOpsManager.permissionToOpCode(requestedPermissionInfo.name)
+ : AppOpsManager.OP_NONE;
+ appOpAllowed = appOp != AppOpsManager.OP_NONE
+ && context.getSystemService(AppOpsManager.class).checkOp(appOp,
+ packageInfo.applicationInfo.uid, packageInfo.packageName)
+ == AppOpsManager.MODE_ALLOWED;
+ }
+
+ Permission permission = new Permission(requestedPermission, granted,
+ appOp, appOpAllowed);
+ group.addPermission(permission);
+ }
+
+ return group;
+ }
+
+ private PermissionGroup(Context context, PackageInfo packageInfo, String name,
+ CharSequence label, String iconPkg, int iconResId) {
+ mContext = context;
+ mPackageInfo = packageInfo;
+ mAppSupportsRuntimePermissions = packageInfo.applicationInfo
+ .targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1;
+ mAppOps = context.getSystemService(AppOpsManager.class);
+ mActivityManager = context.getSystemService(ActivityManager.class);
+ mName = name;
+ mLabel = label;
+ mIconPkg = iconPkg;
+ mIconResId = iconResId;
+ }
+
+ public PackageInfo getApp() {
+ return mPackageInfo;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public String getIconPkg() {
+ return mIconPkg;
+ }
+
+ public int getIconResId() {
+ return mIconResId;
+ }
+
+ public CharSequence getLabel() {
+ return mLabel;
+ }
+
+ public boolean hasPermission(String permission) {
+ return mPermissions.get(permission) != null;
+ }
+
+ public boolean areRuntimePermissionsGranted() {
+ final int permissionCount = mPermissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ Permission permission = mPermissions.valueAt(i);
+ if (mAppSupportsRuntimePermissions) {
+ if (!permission.isGranted()) {
+ return false;
+ }
+ } else if (permission.isGranted() && permission.getAppOp()
+ != AppOpsManager.OP_NONE && !permission.isAppOpAllowed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean grantRuntimePermissions() {
+ final boolean isSharedUser = mPackageInfo.sharedUserId != null;
+ final int uid = mPackageInfo.applicationInfo.uid;
+
+ // We toggle permissions only to apps that support runtime
+ // permissions, otherwise we toggle the app op corresponding
+ // to the permission if the permission is granted to the app.
+ for (Permission permission : mPermissions.values()) {
+ if (mAppSupportsRuntimePermissions) {
+ if (!permission.isGranted()) {
+ mContext.getPackageManager().grantPermission(mPackageInfo.packageName,
+ permission.getName(), new UserHandle(mContext.getUserId()));
+ permission.setGranted(true);
+ }
+ } else {
+ // Legacy apps cannot have a not granted permission but just in case.
+ // Also if the permissions has no corresponding app op, then it is a
+ // third-party one and we do not offer toggling of such permissions.
+ if (!permission.isGranted() || permission.getAppOp() == AppOpsManager.OP_NONE) {
+ continue;
+ }
+
+ if (!permission.isAppOpAllowed()) {
+ // It this is a shared user we want to enable the app op for all
+ // packages in the shared user to match the behavior of this
+ // shared user having a runtime permission.
+ if (isSharedUser) {
+ String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
+ for (String packageName : packageNames) {
+ mAppOps.setMode(permission.getAppOp(), uid, packageName,
+ AppOpsManager.MODE_ALLOWED);
+ }
+ } else {
+ mAppOps.setMode(permission.getAppOp(), uid, mPackageInfo.packageName,
+ AppOpsManager.MODE_ALLOWED);
+ }
+
+ // Legacy apps do not know that they have to retry access to a
+ // resource due to changes in runtime permissions (app ops in this
+ // case). Therefore, we restart them on app op change, so they
+ // can pick up the change.
+ mActivityManager.killUid(uid, KILL_REASON_APP_OP_CHANGE);
+
+ permission.setAppOpAllowed(true);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public boolean revokeRuntimePermissions() {
+ final boolean isSharedUser = mPackageInfo.sharedUserId != null;
+ final int uid = mPackageInfo.applicationInfo.uid;
+
+ // We toggle permissions only to apps that support runtime
+ // permissions, otherwise we toggle the app op corresponding
+ // to the permission if the permission is granted to the app.
+ for (Permission permission : mPermissions.values()) {
+ if (mAppSupportsRuntimePermissions) {
+ if (permission.isGranted()) {
+ mContext.getPackageManager().revokePermission(mPackageInfo.packageName,
+ permission.getName(), new UserHandle(mContext.getUserId()));
+ permission.setGranted(false);
+ }
+ } else {
+ // Legacy apps cannot have a non-granted permission but just in case.
+ // Also if the permission has no corresponding app op, then it is a
+ // third-party one and we do not offer toggling of such permissions.
+ if (!permission.isGranted() || permission.getAppOp() == AppOpsManager.OP_NONE) {
+ continue;
+ }
+
+ if (permission.isAppOpAllowed()) {
+ // It this is a shared user we want to enable the app op for all
+ // packages the the shared user to match the behavior of this
+ // shared user having a runtime permission.
+ if (isSharedUser) {
+ String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
+ for (String packageName : packageNames) {
+ mAppOps.setMode(permission.getAppOp(), uid,
+ packageName, AppOpsManager.MODE_IGNORED);
+ }
+ } else {
+ mAppOps.setMode(permission.getAppOp(), uid,
+ mPackageInfo.packageName, AppOpsManager.MODE_IGNORED);
+ }
+
+ // Disabling an app op may put the app in a situation in which it
+ // has a handle to state it shouldn't have, so we have to kill the
+ // app. This matches the revoke runtime permission behavior.
+ mActivityManager.killUid(uid, KILL_REASON_APP_OP_CHANGE);
+
+ permission.setAppOpAllowed(false);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public List<Permission> getPermissions() {
+ return new ArrayList<>(mPermissions.values());
+ }
+
+ @Override
+ public int compareTo(PermissionGroup another) {
+ final int result = mLabel.toString().compareTo(another.mLabel.toString());
+ if (result == 0) {
+ // Unbadged before badged.
+ return mPackageInfo.applicationInfo.uid
+ - another.mPackageInfo.applicationInfo.uid;
+ }
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ PermissionGroup other = (PermissionGroup) obj;
+
+ if (mName == null) {
+ if (other.mName != null) {
+ return false;
+ }
+ } else if (!mName.equals(other.mName)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return mName != null ? mName.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append(getClass().getSimpleName());
+ builder.append("{name=").append(mName);
+ if (!mPermissions.isEmpty()) {
+ builder.append(", <has permissions>}");
+ } else {
+ builder.append('}');
+ }
+ return builder.toString();
+ }
+
+ void addPermission(Permission permission) {
+ mPermissions.put(permission.getName(), permission);
+ }
+}
+
diff --git a/src/com/android/packageinstaller/permission/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java
index 7ce13f83..a74f08c8 100644
--- a/src/com/android/packageinstaller/permission/ManagePermissionsFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.packageinstaller.permission;
+package com.android.packageinstaller.permission.ui;
import android.annotation.Nullable;
import android.app.ActionBar;
@@ -40,15 +40,18 @@ import android.widget.TextView;
import android.widget.Toast;
import com.android.packageinstaller.R;
+import com.android.packageinstaller.permission.utils.Utils;
+import com.android.packageinstaller.permission.model.AppPermissions;
+import com.android.packageinstaller.permission.model.PermissionGroup;
-public final class ManagePermissionsFragment extends SettingsWithHeader
+public final class AppPermissionsFragment extends SettingsWithHeader
implements OnPreferenceChangeListener {
private static final String LOG_TAG = "ManagePermsFragment";
private AppPermissions mAppPermissions;
- public static ManagePermissionsFragment newInstance(String packageName) {
- ManagePermissionsFragment instance = new ManagePermissionsFragment();
+ public static AppPermissionsFragment newInstance(String packageName) {
+ AppPermissionsFragment instance = new AppPermissionsFragment();
Bundle arguments = new Bundle();
arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
instance.setArguments(arguments);
@@ -136,17 +139,15 @@ public final class ManagePermissionsFragment extends SettingsWithHeader
PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(activity);
mAppPermissions = new AppPermissions(activity, packageInfo, null);
- for (AppPermissions.PermissionGroup group : mAppPermissions.getPermissionGroups()) {
- if (group.hasRuntimePermissions()) {
- SwitchPreference preference = new SwitchPreference(activity);
- preference.setOnPreferenceChangeListener(this);
- preference.setKey(group.getName());
- preference.setIcon(AppPermissions.loadDrawable(pm, group.getIconPkg(),
- group.getIconResId()));
- preference.setTitle(group.getLabel());
- preference.setPersistent(false);
- screen.addPreference(preference);
- }
+ for (PermissionGroup group : mAppPermissions.getPermissionGroups()) {
+ SwitchPreference preference = new SwitchPreference(activity);
+ preference.setOnPreferenceChangeListener(this);
+ preference.setKey(group.getName());
+ preference.setIcon(Utils.loadDrawable(pm, group.getIconPkg(),
+ group.getIconResId()));
+ preference.setTitle(group.getLabel());
+ preference.setPersistent(false);
+ screen.addPreference(preference);
}
setPreferenceScreen(screen);
@@ -155,7 +156,7 @@ public final class ManagePermissionsFragment extends SettingsWithHeader
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String groupName = preference.getKey();
- AppPermissions.PermissionGroup group = mAppPermissions.getPermissionGroup(groupName);
+ PermissionGroup group = mAppPermissions.getPermissionGroup(groupName);
if (group == null) {
return false;
@@ -177,7 +178,7 @@ public final class ManagePermissionsFragment extends SettingsWithHeader
for (int i = 0; i < preferenceCount; i++) {
SwitchPreference preference = (SwitchPreference)
getPreferenceScreen().getPreference(i);
- AppPermissions.PermissionGroup group = mAppPermissions
+ PermissionGroup group = mAppPermissions
.getPermissionGroup(preference.getKey());
if (group != null) {
preference.setChecked(group.areRuntimePermissionsGranted());
diff --git a/src/com/android/packageinstaller/permission/GrantPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionFragment.java
index e751338f..0458f9b9 100644
--- a/src/com/android/packageinstaller/permission/GrantPermissionFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionFragment.java
@@ -14,10 +14,9 @@
* limitations under the License.
*/
-package com.android.packageinstaller.permission;
+package com.android.packageinstaller.permission.ui;
import android.app.Activity;
-import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
@@ -30,6 +29,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.android.packageinstaller.R;
+import com.android.packageinstaller.permission.utils.Utils;
public final class GrantPermissionFragment extends DialogFragment {
public static final String ARG_GROUP_NAME = "ARG_GROUP_NAME";
@@ -97,7 +97,7 @@ public final class GrantPermissionFragment extends DialogFragment {
}
};
- Drawable icon = AppPermissions.loadDrawable(getActivity().getPackageManager(), iconPkg,
+ Drawable icon = Utils.loadDrawable(getActivity().getPackageManager(), iconPkg,
iconResId);
iconView.setImageDrawable(icon);
diff --git a/src/com/android/packageinstaller/permission/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java
index 287d324d..02951e9f 100644
--- a/src/com/android/packageinstaller/permission/GrantPermissionsActivity.java
+++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.packageinstaller.permission;
+package com.android.packageinstaller.permission.ui;
import android.app.Activity;
import android.app.DialogFragment;
@@ -25,19 +25,18 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PermissionInfo;
-import android.graphics.Color;
import android.hardware.camera2.utils.ArrayUtils;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
-import android.text.style.StyleSpan;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
import com.android.packageinstaller.R;
-import com.android.packageinstaller.permission.AppPermissions.Permission;
-import com.android.packageinstaller.permission.AppPermissions.PermissionGroup;
+import com.android.packageinstaller.permission.model.AppPermissions;
+import com.android.packageinstaller.permission.model.Permission;
+import com.android.packageinstaller.permission.model.PermissionGroup;
public class GrantPermissionsActivity extends Activity implements
GrantPermissionFragment.OnRequestGrantPermissionGroupResult {
@@ -87,7 +86,7 @@ public class GrantPermissionsActivity extends Activity implements
mAppPermissions = new AppPermissions(this, callingPackageInfo, mRequestedPermissions);
for (PermissionGroup group : mAppPermissions.getPermissionGroups()) {
- if (group.hasRuntimePermissions() && !group.areRuntimePermissionsGranted()) {
+ if (!group.areRuntimePermissionsGranted()) {
mRequestGrantPermissionGroups.put(group.getName(), new GroupState(group));
}
}
@@ -102,8 +101,7 @@ public class GrantPermissionsActivity extends Activity implements
for (int i = 0; i < groupCount; i++) {
GroupState groupState = mRequestGrantPermissionGroups.valueAt(i);
- if (groupState.mGroup.hasRuntimePermissions()
- && !groupState.mGroup.areRuntimePermissionsGranted()
+ if (!groupState.mGroup.areRuntimePermissionsGranted()
&& groupState.mState == GroupState.STATE_UNKNOWN) {
// Make sure adding the fragment we will remove is not in flight.
getFragmentManager().executePendingTransactions();
diff --git a/src/com/android/packageinstaller/permission/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java
index c9b9daf2..ef117a9c 100644
--- a/src/com/android/packageinstaller/permission/ManagePermissionsActivity.java
+++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.packageinstaller.permission;
+package com.android.packageinstaller.permission.ui;
import android.app.Activity;
import android.app.Fragment;
@@ -38,7 +38,7 @@ public final class ManagePermissionsActivity extends Activity {
finish();
return;
}
- fragment = ManagePermissionsFragment.newInstance(packageName);
+ fragment = AppPermissionsFragment.newInstance(packageName);
} else if (Intent.ACTION_MANAGE_PERMISSION_APPS.equals(action)) {
String permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME);
if (permissionName == null) {
@@ -46,7 +46,7 @@ public final class ManagePermissionsActivity extends Activity {
finish();
return;
}
- fragment = PermissionManagementFragment.newInstance(permissionName);
+ fragment = PermissionAppsFragment.newInstance(permissionName);
} else {
Log.w(LOG_TAG, "Unrecognized action " + action);
finish();
diff --git a/src/com/android/packageinstaller/permission/PermissionManagementFragment.java b/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java
index fbefdc68..f5d7d711 100644
--- a/src/com/android/packageinstaller/permission/PermissionManagementFragment.java
+++ b/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.packageinstaller.permission;
+package com.android.packageinstaller.permission.ui;
import android.annotation.Nullable;
import android.app.ActionBar;
@@ -33,20 +33,22 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.android.packageinstaller.R;
-import com.android.packageinstaller.permission.PermissionApps.Callback;
-import com.android.packageinstaller.permission.PermissionApps.PermissionApp;
+import com.android.packageinstaller.permission.model.PermissionApps;
+import com.android.packageinstaller.permission.model.PermissionApps.Callback;
+import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp;
-public class PermissionManagementFragment extends SettingsWithHeader implements Callback, OnPreferenceChangeListener {
+public final class PermissionAppsFragment extends SettingsWithHeader implements Callback,
+ OnPreferenceChangeListener {
- public static PermissionManagementFragment newInstance(String permissionName) {
- PermissionManagementFragment instance = new PermissionManagementFragment();
+ public static PermissionAppsFragment newInstance(String permissionName) {
+ PermissionAppsFragment instance = new PermissionAppsFragment();
Bundle arguments = new Bundle();
arguments.putString(Intent.EXTRA_PERMISSION_NAME, permissionName);
instance.setArguments(arguments);
return instance;
}
- private PermissionApps mPermissionGroup;
+ private PermissionApps mPermissionApps;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -61,7 +63,7 @@ public class PermissionManagementFragment extends SettingsWithHeader implements
@Override
public void onResume() {
super.onResume();
- mPermissionGroup.refresh();
+ mPermissionApps.refresh();
}
@Override
@@ -99,9 +101,9 @@ public class PermissionManagementFragment extends SettingsWithHeader implements
private void bindUi() {
String groupName = getArguments().getString(Intent.EXTRA_PERMISSION_NAME);
- mPermissionGroup = new PermissionApps(getActivity(), groupName, this);
- final Drawable icon = mPermissionGroup.getIcon();
- final CharSequence label = mPermissionGroup.getLabel();
+ mPermissionApps = new PermissionApps(getActivity(), groupName, this);
+ final Drawable icon = mPermissionApps.getIcon();
+ final CharSequence label = mPermissionApps.getLabel();
setHeader(icon, label, null);
final ViewGroup rootView = (ViewGroup) getView();
@@ -128,7 +130,7 @@ public class PermissionManagementFragment extends SettingsWithHeader implements
setPreferenceScreen(preferences);
}
preferences.removeAll();
- for (PermissionApp app : mPermissionGroup.getApps()) {
+ for (PermissionApp app : mPermissionApps.getApps()) {
SwitchPreference pref = (SwitchPreference) findPreference(app.getKey());
if (pref == null) {
pref = new SwitchPreference(context);
@@ -139,14 +141,14 @@ public class PermissionManagementFragment extends SettingsWithHeader implements
pref.setPersistent(false);
preferences.addPreference(pref);
}
- pref.setChecked(app.hasRuntimePermissions());
+ pref.setChecked(app.areRuntimePermissionsGranted());
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String pkg = preference.getKey();
- PermissionApp app = mPermissionGroup.getApp(pkg);
+ PermissionApp app = mPermissionApps.getApp(pkg);
if (app == null) {
return false;
diff --git a/src/com/android/packageinstaller/permission/SettingsWithHeader.java b/src/com/android/packageinstaller/permission/ui/SettingsWithHeader.java
index c074f6ca..e1e3abe2 100644
--- a/src/com/android/packageinstaller/permission/SettingsWithHeader.java
+++ b/src/com/android/packageinstaller/permission/ui/SettingsWithHeader.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.packageinstaller.permission;
+package com.android.packageinstaller.permission.ui;
import android.content.Intent;
import android.graphics.drawable.Drawable;
diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java
new file mode 100644
index 00000000..0dea8f34
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/utils/Utils.java
@@ -0,0 +1,39 @@
+/*
+ * 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.utils;
+
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+
+public class Utils {
+ private static final String LOG_TAG = "Utils";
+
+ private Utils() {
+ /* do nothing - hide constructor */
+ }
+
+ public static Drawable loadDrawable(PackageManager pm, String pkg, int resId) {
+ try {
+ return pm.getResourcesForApplication(pkg).getDrawable(resId, null);
+ } catch (Resources.NotFoundException | PackageManager.NameNotFoundException e) {
+ Log.d(LOG_TAG, "Couldn't get resource", e);
+ return null;
+ }
+ }
+}