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.
  * <p>
@@ -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<String> 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<String> 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);

相关推荐
千里马学框架11 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台12 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone12 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc13 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo14 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun00770015 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼15 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone16 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen16 小时前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone16 小时前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui