美文网首页
Android Q 上预制旧版应用授权后还会继续弹出授权窗口

Android Q 上预制旧版应用授权后还会继续弹出授权窗口

作者: gale_小米 | 来源:发表于2022-04-20 16:30 被阅读0次

Android 6.0以后由于系统运行安全的考虑,既然在AndroidManifest.xml需要申请权限,对于一些特殊权限需要在app运行时申请权限,并且会在app每次运行的时候弹出没有授权的授权框来然用户授权,PermissionManagerService.java就是负责对系统权限管理的服务

1.在PermissionManagerService.java文件中 updatePermissions()方法中,系统开机起来后就会会更新应用的权限

  1. 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;
+                                }
                             }
                         }
                     }

相关文章

网友评论

      本文标题:Android Q 上预制旧版应用授权后还会继续弹出授权窗口

      本文链接:https://www.haomeiwen.com/subject/vxhpfrtx.html