Android O PackageInstaller 解析
Android O 8.0
1.src\com\android\packageinstaller\permission\mode\PermissionGroups.java
@Override public List<PermissionGroup> loadInBackground() { ArraySet<String> launcherPkgs = Utils.getLauncherPackages(getContext()); PermissionApps.PmCache pmCache = new PermissionApps.PmCache( getContext().getPackageManager()); List<PermissionGroup> groups = new ArrayList<>(); Set<String> seenPermissions = new ArraySet<>(); PackageManager packageManager = getContext().getPackageManager(); List<PermissionGroupInfo> groupInfos = packageManager.getAllPermissionGroups(0); for (PermissionGroupInfo groupInfo : groupInfos) { // Mare sure we respond to cancellation. if (isLoadInBackgroundCanceled()) { return Collections.emptyList(); } // 得到权限组里的所有权限 // Get the permissions in this group. final List<PermissionInfo> groupPermissions; try { groupPermissions = packageManager.queryPermissionsByGroup(groupInfo.name, 0); } catch (PackageManager.NameNotFoundException e) { continue; } boolean hasRuntimePermissions = false; // 查看某个权限组是否含有运行时权限 // Cache seen permissions and see if group has runtime permissions. for (PermissionInfo groupPermission : groupPermissions) { seenPermissions.add(groupPermission.name); if ((groupPermission.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS && (groupPermission.flags & PermissionInfo.FLAG_INSTALLED) != 0 && (groupPermission.flags & PermissionInfo.FLAG_REMOVED) == 0) { hasRuntimePermissions = true; } } // 权限组里没有运行时权限,我们不感兴趣,继续循环查询 // No runtime permissions - not interesting for us. if (!hasRuntimePermissions) { continue; } // 如果权限组里含有运行时权限,则继续往下执行 // 获取权限组的label CharSequence label = loadItemInfoLabel(groupInfo); Drawable icon = loadItemInfoIcon(groupInfo); // 根据权限组 新建 PermissionApps 对象 PermissionApps permApps = new PermissionApps(getContext(), groupInfo.name, null, pmCache); permApps.refreshSync(); // 创建 PermissionGroup 对象 // Create the group and add to the list. PermissionGroup group = new PermissionGroup(groupInfo.name, groupInfo.packageName, label, icon, permApps.getTotalCount(launcherPkgs), permApps.getGrantedCount(launcherPkgs)); groups.add(group); } // 获取所有的安装包权限 // Make sure we add groups for lone runtime permissions. List<PackageInfo> installedPackages = getContext().getPackageManager() .getInstalledPackages(PackageManager.GET_PERMISSIONS); // We will filter out permissions that no package requests. Set<String> requestedPermissions = new ArraySet<>(); for (PackageInfo installedPackage : installedPackages) { if (installedPackage.requestedPermissions == null) { continue; } // 将安装包请求的权限加入到 列表中 for (String requestedPermission : installedPackage.requestedPermissions) { requestedPermissions.add(requestedPermission); } } for (PackageInfo installedPackage : installedPackages) { if (installedPackage.permissions == null) { continue; } // 自定义的权限 for (PermissionInfo permissionInfo : installedPackage.permissions) { // If we have handled this permission, no more work to do. if (!seenPermissions.add(permissionInfo.name)) { continue; } // 关心的是 运行时权限 // We care only about installed runtime permissions. if ((permissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) != PermissionInfo.PROTECTION_DANGEROUS || (permissionInfo.flags & PermissionInfo.FLAG_INSTALLED) == 0) { continue; } // 没有app使用那个自定义的权限 // If no app uses this permission, if (!requestedPermissions.contains(permissionInfo.name)) { continue; } CharSequence label = loadItemInfoLabel(permissionInfo); Drawable icon = loadItemInfoIcon(permissionInfo); PermissionApps permApps = new PermissionApps(getContext(), permissionInfo.name, null, pmCache); permApps.refreshSync(); // Create the group and add to the list. PermissionGroup group = new PermissionGroup(permissionInfo.name, permissionInfo.packageName, label, icon, permApps.getTotalCount(launcherPkgs), permApps.getGrantedCount(launcherPkgs)); groups.add(group); } } Collections.sort(groups); return groups; }
2.PermissionApps.java
/** * Refresh the state and do not return until it finishes. Should not be called while an {@link * #refresh async referesh} is in progress. */ public void refreshSync() { mSkipUi = true; createMap(loadPermissionApps()); }
3.
src\com\android\packageinstaller\permission\utils\EventLogger.java
/** * For each permission there are four events. The events are in the order of * #ALL_DANGEROUS_PERMISSIONS. The four events per permission are (in that order): "requested", * "granted", "denied", and "revoked". */ public class EventLogger { private static final String LOG_TAG = EventLogger.class.getSimpleName(); /** All dangerous permission names in the same order as the events in MetricsEvent */ private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList( Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR, Manifest.permission.CAMERA, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS, Manifest.permission.GET_ACCOUNTS, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE, Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG, Manifest.permission.ADD_VOICEMAIL, Manifest.permission.USE_SIP, Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.READ_CELL_BROADCASTS, Manifest.permission.BODY_SENSORS, Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS, Manifest.permission.RECEIVE_WAP_PUSH, Manifest.permission.RECEIVE_MMS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_NUMBERS, Manifest.permission.ANSWER_PHONE_CALLS, Manifest.permission.ACCEPT_HANDOVER); private static final List<String> ALL_APPOP_PERMISSIONS = Arrays.asList( Manifest.permission.ACCESS_NOTIFICATIONS, Manifest.permission.SYSTEM_ALERT_WINDOW, Manifest.permission.WRITE_SETTINGS, Manifest.permission.REQUEST_INSTALL_PACKAGES); ...... }
4.
src\com\android\packageinstaller\permission\utils\Utils.java
public static final String OS_PKG = "android"; public static final String[] MODERN_PERMISSION_GROUPS = { // 目前平台支持的权限组 Manifest.permission_group.CALENDAR, Manifest.permission_group.CAMERA, Manifest.permission_group.CONTACTS, Manifest.permission_group.LOCATION, Manifest.permission_group.SENSORS, Manifest.permission_group.SMS, Manifest.permission_group.PHONE, Manifest.permission_group.MICROPHONE, Manifest.permission_group.STORAGE }; private static final Intent LAUNCHER_INTENT = new Intent(Intent.ACTION_MAIN, null) .addCategory(Intent.CATEGORY_LAUNCHER);
5.
DeviceUtils.java
public class DeviceUtils { public static boolean isTelevision(Context context) { // 电视 int uiMode = context.getResources().getConfiguration().uiMode; return (uiMode & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION; } public static boolean isWear(final Context context) {// 穿戴设备 return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH); } public static boolean isAuto(Context context) {// 汽车、自动设备 return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); } }