Android Q 上预制旧版应用授权后还会继续弹出授权窗口
2022-04-20 本文已影响0人
gale_小米
Android 6.0以后由于系统运行安全的考虑,既然在AndroidManifest.xml需要申请权限,对于一些特殊权限需要在app运行时申请权限,并且会在app每次运行的时候弹出没有授权的授权框来然用户授权,PermissionManagerService.java就是负责对系统权限管理的服务
1.在PermissionManagerService.java文件中 updatePermissions()方法中,系统开机起来后就会会更新应用的权限
- updatePermissions() --->restorePermissionState() (开机默认给应用授权)
private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
private void updatePermissions(String packageName, PackageParser.Package pkg,
boolean replaceGrant, Collection<PackageParser.Package> allPackages,
PermissionCallback callback) {
final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
(replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
updatePermissions(
packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
if (pkg != null && pkg.childPackages != null) {
for (PackageParser.Package childPkg : pkg.childPackages) {
updatePermissions(childPkg.packageName, childPkg,
getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
}
}
}
private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
final int flags = UPDATE_PERMISSIONS_ALL |
(sdkUpdated
? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
: 0);
updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
}
private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
PermissionCallback callback) {
// TODO: Most of the methods exposing BasePermission internals [source package name,
// etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
// have package settings, we should make note of it elsewhere [map between
// source package name and BasePermission] and cycle through that here. Then we
// define a single method on BasePermission that takes a PackageSetting, changing
// package name and a package.
// NOTE: With this approach, we also don't need to tree trees differently than
// normal permissions. Today, we need two separate loops because these BasePermission
// objects are stored separately.
// Make sure there are no dangling permission trees.
flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
// Make sure all dynamic permissions have been assigned to a package,
// and make sure there are no dangling permissions.
flags = updatePermissions(changingPkgName, changingPkg, flags, callback);
synchronized (mLock) {
if (mBackgroundPermissions == null) {
// Cache background -> foreground permission mapping.
// Only system declares background permissions, hence mapping does never change.
mBackgroundPermissions = new ArrayMap<>();
for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
if (bp.perm != null && bp.perm.info != null
&& bp.perm.info.backgroundPermission != null) {
String fgPerm = bp.name;
String bgPerm = bp.perm.info.backgroundPermission;
List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
if (fgPerms == null) {
fgPerms = new ArrayList<>();
mBackgroundPermissions.put(bgPerm, fgPerms);
}
fgPerms.add(fgPerm);
}
}
}
}
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
// Now update the permissions for all packages, in particular
// replace the granted permissions of the system packages.
if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
for (PackageParser.Package pkg : allPackages) {
if (pkg != changingPkg) {
// Only replace for packages on requested volume
final String volumeUuid = getVolumeUuidForPackage(pkg);
final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
&& Objects.equals(replaceVolumeUuid, volumeUuid);
restorePermissionState(pkg, replace, changingPkgName, callback);
}
}
}
if (changingPkg != null) {
// Only replace for packages on requested volume
final String volumeUuid = getVolumeUuidForPackage(changingPkg);
final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
&& Objects.equals(replaceVolumeUuid, volumeUuid);
restorePermissionState(changingPkg, replace, changingPkgName, callback);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
private int updatePermissions(String packageName, PackageParser.Package pkg, int flags,
@Nullable PermissionCallback callback) {
Set<BasePermission> needsUpdate = null;
synchronized (mLock) {
final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
while (it.hasNext()) {
final BasePermission bp = it.next();
if (bp.isDynamic()) {
bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
}
if (bp.getSourcePackageSetting() != null) {
if (packageName != null && packageName.equals(bp.getSourcePackageName())
&& (pkg == null || !hasPermission(pkg, bp.getName()))) {
Slog.i(TAG, "Removing old permission tree: " + bp.getName()
+ " from package " + bp.getSourcePackageName());
if (bp.isRuntime()) {
final int[] userIds = mUserManagerInt.getUserIds();
final int numUserIds = userIds.length;
for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
final int userId = userIds[userIdNum];
mPackageManagerInt.forEachPackage((Package p) -> {
final String pName = p.packageName;
final ApplicationInfo appInfo =
mPackageManagerInt.getApplicationInfo(pName, 0,
Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
if (appInfo != null
&& appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
return;
}
final String permissionName = bp.getName();
if (checkPermission(permissionName, pName, Process.SYSTEM_UID,
userId) == PackageManager.PERMISSION_GRANTED) {
try {
revokeRuntimePermission(
permissionName,
pName,
false,
userId,
callback);
} catch (IllegalArgumentException e) {
Slog.e(TAG,
"Failed to revoke "
+ permissionName
+ " from "
+ pName,
e);
}
}
});
}
}
flags |= UPDATE_PERMISSIONS_ALL;
it.remove();
}
continue;
}
if (needsUpdate == null) {
needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
}
needsUpdate.add(bp);
}
}
if (needsUpdate != null) {
for (final BasePermission bp : needsUpdate) {
final PackageParser.Package sourcePkg =
mPackageManagerInt.getPackage(bp.getSourcePackageName());
synchronized (mLock) {
if (sourcePkg != null && sourcePkg.mExtras != null) {
final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
if (bp.getSourcePackageSetting() == null) {
bp.setSourcePackageSetting(sourcePs);
}
continue;
}
Slog.w(TAG, "Removing dangling permission: " + bp.getName()
+ " from package " + bp.getSourcePackageName());
mSettings.removePermissionLocked(bp.getName());
}
}
}
return flags;
}
先对如下权限进行说明GRANT_DENIED 、GRANT_INSTALL 、GRANT_INSTALL_LEGACY 、GRANT_RUNTIME 、GRANT_UPGRADE
GRANT_DENIED =1 ,不授予权限
GRANT_INSTALL = 2; 授予权限作为安装权限
GRANT_INSTALL_LEGACY = 3;授予作为一个旧的应用程序的安装权限的权限
GRANT_RUNTIME = 4; 授予运行运行时的权限
GRANT_UPGRADE = 5; 授予作为运行时一个被授予的权限,作为一个安装时间
解决方案:
普通预装也可以在应用安装时进行修改
Index: PreinstallApks.java
===================================================================
--- PreinstallApks.java
+++ PreinstallApks.java
@@ -242,7 +242,8 @@
Log.d(TAG, "invokeInstallPackage inPath="+inPath);
try {
final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
- sessionParams.installFlags = flags;
+ sessionParams.installFlags |= PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
+ sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
final int sessionId = mContext.getPackageManager().getPackageInstaller().createSession(sessionParams);
session = mContext.getPackageManager().getPackageInstaller().openSession(sessionId);
writeSplitToInstallSession(session, inPath, "base.apk");
方式2:预装系统应用时
Index: PermissionManagerService.java
===================================================================
@@ -1008,7 +1008,10 @@
final String perm = bp.getName();
boolean allowedSig = false;
int grant = GRANT_DENIED;
-
+ if (TextUtils.equals(pkg.packageName,"com.jxw.launcher")){
+ Log.i(TAG, "packageName for package " + pkg.packageName);
+ grant = GRANT_INSTALL;
+ }
// Keep track of app op permissions.
if (bp.isAppOp()) {
mSettings.addAppOpPackage(perm, pkg.packageName);
@@ -1022,7 +1025,11 @@
|| upgradedActivityRecognitionPermission != null) {
// Before Q we represented some runtime permissions as install permissions,
// in Q we cannot do this anymore. Hence upgrade them all.
- grant = GRANT_UPGRADE;
+ if (TextUtils.equals(pkg.packageName,"com.jxw.launcher")){
+ grant = GRANT_INSTALL;
+ }else{
+ grant = GRANT_RUNTIME;
+ }
} else {
// For modern apps keep runtime permissions unchanged.
- grant = GRANT_RUNTIME;
+ if (TextUtils.equals(pkg.packageName,"com.jxw.launcher")){
+ grant = GRANT_INSTALL;
+ }else{
+ grant = GRANT_RUNTIME;
+ }
}
} else if (bp.isSignature()) {
// For all apps signature permissions are install time ones.
allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
if (allowedSig) {
- grant = GRANT_INSTALL;
+ // For modern apps keep runtime permissions unchanged.
+ if (TextUtils.equals(pkg.packageName,"com.jxw.launcher")){
+ grant = GRANT_INSTALL;
+ }else{
+ grant = GRANT_UPGRADE;
+ }
}
}
@@ -1050,7 +1059,11 @@
// to the platform (note: need to only do this when
// updating the platform).
if (!isNewPlatformPermissionForPackage(perm, pkg)) {
- grant = GRANT_DENIED;
+ if (TextUtils.equals(pkg.packageName,"com.jxw.launcher")){
+ grant = GRANT_INSTALL;
+ }else{
+ grant = GRANT_DENIED;
+ }
}
}
}