android 11安装apk自动获取权限

由于android 11以上版本对于读写权限的进一步限制,安装的apk获取权限的流程又加了一步,对于客户来说多半步也算复杂,Android 保存/读取本地SD卡文件(兼容Android 13)

根据之前的经验,在安装流程后打开全部权限即可。

Index: frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
===================================================================
--- frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java	(版本 2518)
+++ frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java	(工作副本)
@@ -221,6 +221,8 @@
 import com.android.server.pm.pkg.component.ParsedUsesPermissionImpl;
 // @}
 
+import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
+
 final class InstallPackageHelper {
 
@@ -281,6 +283,7 @@
     private final ViewCompiler mViewCompiler;
     private final SharedLibrariesImpl mSharedLibraries;
     private final PackageManagerServiceInjector mInjector;
+    private final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
 
     // TODO(b/198166813): remove PMS dependency
     InstallPackageHelper(PackageManagerService pm, AppDataHelper appDataHelper) {
@@ -310,6 +313,7 @@
         mAlwaysAllowInstallApks = mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_always_allowed_install_apks);
+        mDefaultPermissionPolicy =  new DefaultPermissionGrantPolicy(mContext);
     }
 
     InstallPackageHelper(PackageManagerService pm) {
@@ -388,6 +392,19 @@
                 // Attempt the transparent shared UID migration
                 mPm.mSettings.convertSharedUserSettingsLPw(sharedUserSetting);
             }
+        } else {
+            final Object obj = mPm.mSettings.getSettingLPr(pkgSetting.getAppId());
+            if (obj instanceof SharedUserSetting) {
+                try {
+                    synchronized (mPm.mLock) {
+                        mPm.mSettings.registerAppIdLPw(pkgSetting, true);
+                        Slog.d(TAG, "The AppId of " + pkgSetting.getName() + " changes from "
+                            + ((SharedUserSetting)obj).getAppId() + " to " + pkgSetting.getAppId());
+                    }
+                } catch (PackageManagerException e) {
+                    Slog.e(TAG, "register new app id for " + pkgSetting + " error:", e);
+                }
+            }
         }
         if (reconciledPkg.mInstallArgs != null
                 && reconciledPkg.mInstallArgs.mForceQueryableOverride) {
@@ -2386,9 +2403,25 @@
                     // The caller explicitly specified INSTALL_ALL_USERS flag.
                     // Thus, updating the settings to install the app for all users.
                     for (int currentUserId : allUsers) {
-                        ps.setInstalled(true, currentUserId);
-                        ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId,
+                        // If the app is already installed for the currentUser,
+                        // keep it as installed as we might be updating the app at this place.
+                        // If not currently installed, check if the currentUser is restricted by
+                        // DISALLOW_INSTALL_APPS or DISALLOW_DEBUGGING_FEATURES device policy.
+                        // Install / update the app if the user isn't restricted. Skip otherwise.
+                        final boolean installedForCurrentUser = ArrayUtils.contains(
+                                installedForUsers, currentUserId);
+                        final boolean restrictedByPolicy =
+                                mPm.isUserRestricted(currentUserId,
+                                        UserManager.DISALLOW_INSTALL_APPS)
+                                || mPm.isUserRestricted(currentUserId,
+                                        UserManager.DISALLOW_DEBUGGING_FEATURES);
+                        if (installedForCurrentUser || !restrictedByPolicy) {
+                            ps.setInstalled(true, currentUserId);
+                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId,
                                 installerPackageName);
+                        } else {
+                            ps.setInstalled(false, currentUserId);
+                        }
                     }
                 }
 
@@ -2505,6 +2538,18 @@
         }
     }
 
+    private void enableManageExternalStorage(String pkgName, int appId) {
+        final AppOpsManager appOpsManager = mPm.mContext.getSystemService(AppOpsManager.class);
+        final int[] allUsersList = mPm.mUserManager.getUserIds();
+        for (int userId : allUsersList) {
+            final int uid = UserHandle.getUid(userId, appId);
+            appOpsManager.setMode(AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE,
+                    uid,
+                    pkgName,
+                    AppOpsManager.MODE_ALLOWED);
+        }
+    }
+
     /**
      * On successful install, executes remaining steps after commit completes and the package lock
      * is released. These are typically more expensive or require calls to installd, which often
@@ -2938,6 +2983,11 @@
         final boolean removedBeforeUpdate = (pkgSetting == null)
                 || (pkgSetting.isSystem() && !pkgSetting.getPath().getPath().equals(
                 res.mPkg.getPath()));
+        mDefaultPermissionPolicy.grantAppRuntimePermissions(packageName);
+        int resAppId = UserHandle.getAppId(res.mUid);
+        enableManageExternalStorage(packageName, resAppId);
         if (succeeded && removedBeforeUpdate) {
             Slog.e(TAG, packageName + " was removed before handlePackagePostInstall "
                     + "could be executed");
Index: frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
===================================================================
--- frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java	(版本 2518)
+++ frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java	(工作副本)
@@ -287,6 +287,8 @@
 import com.android.server.pm.pkg.component.ParsedUsesPermission;
 // @}
 
+import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
+
 /**
  * Keep track of all those APKs everywhere.
  * 

@@ -864,7 +866,7 @@ // Internal interface for permission manager final PermissionManagerServiceInternal mPermissionManager; - + final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; @Watched final ComponentResolver mComponentResolver; @@ -1649,6 +1651,7 @@ mLock = injector.getLock(); mPackageStateWriteLock = mLock; mPermissionManager = injector.getPermissionManagerServiceInternal(); + mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(mContext); mSettings = injector.getSettings(); mUserManager = injector.getUserManagerService(); mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager); @@ -1780,6 +1783,7 @@ mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager); mComponentResolver = injector.getComponentResolver(); mPermissionManager = injector.getPermissionManagerServiceInternal(); + mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(mContext); mSettings = injector.getSettings(); mIncrementalManager = mInjector.getIncrementalManager(); mDefaultAppProvider = mInjector.getDefaultAppProvider(); @@ -4485,6 +4489,10 @@ final Message msg = mHandler.obtainMessage(PackageManagerService.POST_INSTALL, token, didLaunch ? 1 : 0); mHandler.sendMessage(msg); + PostInstallData data = mRunningInstalls.get(msg.arg1); + InstallArgs args = data.args; + String packageName = args.mInstallSource.installerPackageName; + mDefaultPermissionPolicy.grantAppRuntimePermissions(packageName); } void checkPackageStartable(@NonNull Computer snapshot, @NonNull String packageName, Index: frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java =================================================================== --- frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java (版本 2518) +++ frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java (工作副本) @@ -87,6 +87,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import android.os.Binder; // CTA Feature: add permission @{ import android.cta.CtaPermFactory; @@ -104,7 +105,7 @@ * to have an interface defined in the package manager but have the impl next to other * policy stuff like PhoneWindowManager */ -final class DefaultPermissionGrantPolicy { +final public class DefaultPermissionGrantPolicy { private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars private static final boolean DEBUG = false; @@ -336,7 +337,7 @@ } }; - DefaultPermissionGrantPolicy(@NonNull Context context) { + public DefaultPermissionGrantPolicy(@NonNull Context context) { mContext = context; HandlerThread handlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); @@ -437,6 +438,43 @@ grantRuntimePermissionsForSystemPackage(pm, userId, pkg, null); } + private void grantRuntimePermissionsForPackage(int userId, PackageInfo pkg) { + Set permissions = new ArraySet<>(); + DelayingPackageManagerCache pm = new DelayingPackageManagerCache(); + String [] pkgPermissions = pkg.requestedPermissions; + if(pkgPermissions== null || pkgPermissions.length==0)return; + for (String permission : pkgPermissions) { + final PermissionInfo perm = pm.getPermissionInfo(permission); + if (perm == null) { + continue; + } + if (perm.isRuntime()) { + Log.i(TAG, "Granting run permission="+permission); + permissions.add(permission); + } + } + if (!permissions.isEmpty()) { + grantRuntimePermissions(pm,pkg, permissions, true, userId); + } + pm.apply(); + } + + public void grantAppRuntimePermissions(String pkgName) { + Log.i(TAG, "grantAppRuntimePermissions--pkgName:"+pkgName); + final long ident = Binder.clearCallingIdentity(); + try { + final PackageInfo pkg = NO_PM_CACHE.getPackageInfo(pkgName); + Log.i(TAG, "pkg=" + pkg); + if (pkg != null) { + grantRuntimePermissionsForPackage(UserHandle.USER_SYSTEM, pkg); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + private void grantRuntimePermissionsForSystemPackage(PackageManagerWrapper pm, int userId, PackageInfo pkg, Set filterPermissions) { if (ArrayUtils.isEmpty(pkg.requestedPermissions)) { @@ -497,13 +535,13 @@ pm.addPackageInfo(pkg.packageName, pkg); - if (!pm.isSysComponentOrPersistentPlatformSignedPrivApp(pkg) - || !doesPackageSupportRuntimePermissions(pkg) - || ArrayUtils.isEmpty(pkg.requestedPermissions)) { + if (/*!pm.isSysComponentOrPersistentPlatformSignedPrivApp(pkg) + || !doesPackageSupportRuntimePermissions(pkg) + || */ArrayUtils.isEmpty(pkg.requestedPermissions)) { continue; }

验证结构显示:
mDefaultPermissionPolicy.grantAppRuntimePermissions(packageName);为获取除android.permission.MANAGE_EXTERNAL_STORAGE外的所有权限
为了解决android.permission.MANAGE_EXTERNAL_STORAGE,需要额外添加enableManageExternalStorage(packageName, resAppId);

你可能感兴趣的:(android_system,android,permission,storage)