1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.packageinstaller.permission.model; 17 18import android.content.BroadcastReceiver; 19import android.content.Context; 20import android.content.Intent; 21import android.content.pm.PackageInfo; 22import android.content.pm.PackageManager; 23import android.content.pm.PackageManager.NameNotFoundException; 24import android.util.ArrayMap; 25import android.util.ArraySet; 26 27import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; 28import com.android.packageinstaller.permission.utils.Utils; 29 30import java.text.Collator; 31import java.util.ArrayList; 32import java.util.Collections; 33 34public class PermissionStatusReceiver extends BroadcastReceiver { 35 @Override 36 public void onReceive(Context context, Intent intent) { 37 int[] counts = new int[3]; 38 ArrayList<CharSequence> grantedGroups = new ArrayList<>(); 39 boolean succeeded = false; 40 41 boolean isForPackage = intent.hasExtra(Intent.EXTRA_PACKAGE_NAME); 42 43 Intent responseIntent = new Intent(intent.getStringExtra( 44 Intent.EXTRA_GET_PERMISSIONS_RESPONSE_INTENT)); 45 responseIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); 46 47 48 if (isForPackage) { 49 String pkg = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); 50 succeeded = getPermissionsCount(context, pkg, counts, grantedGroups); 51 } else { 52 succeeded = getAppsWithPermissionsCount(context, counts); 53 } 54 if (succeeded) { 55 responseIntent.putExtra(Intent.EXTRA_GET_PERMISSIONS_COUNT_RESULT, counts); 56 57 if (isForPackage) { 58 responseIntent.putExtra(Intent.EXTRA_GET_PERMISSIONS_GROUP_LIST_RESULT, 59 grantedGroups.toArray(new CharSequence[grantedGroups.size()])); 60 } 61 } 62 63 context.sendBroadcast(responseIntent); 64 } 65 66 public boolean getPermissionsCount(Context context, String pkg, int[] counts, 67 ArrayList<CharSequence> grantedGroups) { 68 try { 69 PackageInfo packageInfo = 70 context.getPackageManager().getPackageInfo(pkg, PackageManager.GET_PERMISSIONS); 71 AppPermissions appPermissions = 72 new AppPermissions(context, packageInfo, null, false, null); 73 int grantedCount = 0; 74 int totalCount = 0; 75 int additionalCount = 0; 76 77 for (AppPermissionGroup group : appPermissions.getPermissionGroups()) { 78 if (Utils.shouldShowPermission(group, pkg)) { 79 totalCount++; 80 if (group.areRuntimePermissionsGranted()) { 81 grantedCount++; 82 83 if (Utils.OS_PKG.equals(group.getDeclaringPackage())) { 84 grantedGroups.add(group.getLabel()); 85 } else { 86 additionalCount++; 87 } 88 } 89 } 90 } 91 92 // Sort 93 Collator coll = Collator.getInstance(); 94 coll.setStrength(Collator.PRIMARY); 95 Collections.sort(grantedGroups, coll); 96 97 // Set results 98 counts[0] = grantedCount; 99 counts[1] = totalCount; 100 counts[2] = additionalCount; 101 102 return true; 103 } catch (NameNotFoundException e) { 104 return false; 105 } 106 } 107 108 public boolean getAppsWithPermissionsCount(Context context, int[] counts) { 109 ArraySet<String> launcherPkgs = Utils.getLauncherPackages(context); 110 // Indexed by uid. 111 ArrayMap<String, Boolean> grantedApps = new ArrayMap<>(); 112 ArrayMap<String, Boolean> allApps = new ArrayMap<>(); 113 for (String group : Utils.MODERN_PERMISSION_GROUPS) { 114 PermissionApps permissionApps = new PermissionApps(context, 115 group, null); 116 permissionApps.loadNowWithoutUi(); 117 for (PermissionApp app : permissionApps.getApps()) { 118 String key = app.getKey(); 119 if (Utils.isSystem(app, launcherPkgs)) { 120 // We default to not showing system apps, so hide them from count. 121 continue; 122 } 123 if (app.areRuntimePermissionsGranted()) { 124 grantedApps.put(key, true); 125 } 126 allApps.put(key, true); 127 } 128 } 129 counts[0] = grantedApps.size(); 130 counts[1] = allApps.size(); 131 return true; 132 } 133} 134