Android9.0/8.1/6.0 默认给系统 app 授予所有权限

简介: Android9.0/8.1/6.0 默认给系统 app 授予所有权限

前言


最近和 PackageManagerService(PMS) 杠上了,3W 多行代码,着实精妙。网上有很多分析流程的文章,这里我就不再复述了,就来看下 PMS 的衍生修改实战吧。之前写过一篇 Android8.1 默认给第三方 app 授予所有权限,其实也能给系统 app 授权,原理大概为收到开机广播后去检查指定包名权限是否已经赋予,未授权则授权。但开机广播有时效性,有些场景不能满足要求,况且总需要去修改源码,不方便。


修改


大致思路如下,参考 MTK 的系统 app 可卸载配置方案,在

vendor\mediatek\proprietary\frameworks\base\data\etc\pms_sysapp_removable_system_list.txt

中增加可卸载系统 app 包名,在编译时拷贝至 out system/etc/permissions 路径下, 在 PmsExtImpl.java 中读取该文件,PMS 在扫描时判断包名是否在 pms_sysapp_removable_system_list 列表中,确定是否可卸载。


一、新建 pms_sysapp_grant_permission_list.txt


vendor\mediatek\proprietary\frameworks\base\data\etc\pms_sysapp_grant_permission_list.txt


com.android.dialer
com.android.soundrecorder
com.android.browser
com.mediatek.filemanager
com.android.calendar
com.android.email

二、拷贝 pms_sysapp_grant_permission_list.txt 至 out 目录下


device/mediatek/common/device.mk

 ifneq ($(strip $(MTK_BASIC_PACKAGE)), yes)
+  PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_grant_permission_list.txt:system/etc/permissions/pms_sysapp_grant_permission_list.txt)
   PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_system_list.txt:system/etc/permissions/pms_sysapp_removable_system_list.txt)
   PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_vendor_list.txt:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/pms_sysapp_removable_vendor_list.txt)
 endif

三、PMS 中系统启动完成读取 pms_sysapp_grant_permission_list.txt,给 app 授权


frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java

@Override
    public void systemReady() {
        enforceSystemOrRoot("Only the system can claim the system is ready");
    //cczheng add for system app grant permission S
        if (mFirstBoot) {
            MTKPackageManagerUtil.slientGrantRuntimePermission(mContext);
        }
    //cczheng add for system app grant permission E
        mSystemReady = true;
        final ContentResolver resolver = mContext.getContentResolver();
        ContentObserver co = new ContentObserver(mHandler) {
            @Override
            public void onChange(boolean selfChange) {
                mEphemeralAppsDisabled =
                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
            }
        };
        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
                false, co, UserHandle.USER_SYSTEM);
        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
        co.onChange(true);


新增 MTKPackageManagerUtil 类

1、读取 pms_sysapp_grant_permission_list.txt 中包名

2、遍历包名集合获取需要申请的权限集合

3、根据权限名称判断当前包名是否已经授权,未授权则授权

此处有几个坑说一下,

坑一、根据包名获取到的权限集合中有很多不在BasePermission中, 系统不能正常授权,会抛异常,导致后续的权限不能正常授权,需要剔除这部分。

2019-01-01 08:23:51.605 656-656/system_process W/System.err:     at com.android.server.pm.PackageManagerService.grantRuntimePermission(PackageManagerService.java:5732)
2019-01-01 08:23:51.605 656-656/system_process W/System.err:     at com.android.server.pm.PackageManagerService.grantRuntimePermission(PackageManagerService.java:5703)
2019-01-01 08:23:51.605 656-656/system_process W/System.err:     at android.app.ApplicationPackageManager.grantRuntimePermission(ApplicationPackageManager.java:627)
2019-01-01 08:23:51.605 656-656/system_process W/System.err:     at com.android.server.pm.MTKPackageManagerUtil.slientGrantRuntimePermission(MTKPackageManagerUtil.java:90)
2019-01-01 08:23:51.605 656-656/system_process W/System.err:     at com.android.server.pm.PackageManagerService.systemReady(PackageManagerService.java:22551)
2019-01-01 08:23:51.605 656-656/system_process D/MTKPackageManagerUtil: Unknown permission: com.qualcomm.permission.USE_PHONE_SERVICE

坑二、用户自己声明的权限和非运行时权限,需要剔除这部分。

2019-01-01 08:43:51.605 656-656/system_process W/System.err:     at com.android.server.pm.PackageManagerService.enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageManagerService.java:5696)
2019-01-01 08:43:51.605 656-656/system_process W/System.err:     at com.android.server.pm.PackageManagerService.grantRuntimePermission(PackageManagerService.java:5740)
2019-01-01 08:43:51.605 656-656/system_process W/System.err:     at com.android.server.pm.PackageManagerService.grantRuntimePermission(PackageManagerService.java:5703)
2019-01-01 08:43:51.605 656-656/system_process W/System.err:     at android.app.ApplicationPackageManager.grantRuntimePermission(ApplicationPackageManager.java:627)
2019-01-01 08:43:51.605 656-656/system_process W/System.err:     at com.android.server.pm.MTKPackageManagerUtil.slientGrantRuntimePermission(MTKPackageManagerUtil.java:90)
2019-01-01 08:43:51.605 656-656/system_process W/System.err:     at com.android.server.pm.PackageManagerService.systemReady(PackageManagerService.java:22551)
2019-01-01 08:43:51.605 656-656/system_process D/MTKPackageManagerUtil: Permission android.permission.ACCESS_BLUETOOTH_SHARE is not a changeable permission type

frameworks\base\services\core\java\com\android\server\pm\MTKPackageManagerUtil.java

/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.pm;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.Process;
import android.text.TextUtils;
import android.util.Log;
import android.content.pm.IPackageManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.Manifest;
import com.android.internal.util.ArrayUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
public class MTKPackageManagerUtil{
    private static String TAG = "KEPackageManagerUtil";
    //copy from vendor\mediatek\proprietary\frameworks\base\services\core\java\com\mediatek\server\pm\PmsExtImpl.java
    private static final File GRANT_SYS_APP_LIST_SYSTEM = Environment
            .buildPath(Environment.getRootDirectory(), "etc", "permissions",
                    "pms_sysapp_grant_permission_list.txt");
    private static HashSet<String> sGrantSystemAppSet = new HashSet<String>();
    private static HashSet<String> sGrantPermissionSet = new HashSet<String>();
    private static  IPackageManager mIpm;
    private static  AppOpsManager mAppOpsManager;
    public static void slientGrantRuntimePermission(Context mContext, Settings mSettings){
        sGetGrantSystemAppFromFile(sGrantSystemAppSet, GRANT_SYS_APP_LIST_SYSTEM);
        PackageManager mPackageManager = mContext.getPackageManager();
        mIpm = AppGlobals.getPackageManager();
        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        Iterator<String> it = sGrantSystemAppSet.iterator();
        Log.d(TAG, "sGrantSystemAppSet:");
        while (it.hasNext()) {
            sGrantPermissionSet.clear();
            String pkgName = it.next();
            Log.d(TAG, "pkgName="+pkgName);
            try {
                PackageInfo mPackageInfo =   mPackageManager.getPackageInfo(pkgName, PackageManager.GET_PERMISSIONS);
                 for (String permission : mPackageInfo.requestedPermissions){
                     int status = mPackageManager.checkPermission(permission, pkgName);
                     final BasePermission bp = mSettings.mPermissions.get(permission);
                     if (status != PackageManager.PERMISSION_GRANTED && bp != null) {
                        if (!bp.isRuntime() && !bp.isDevelopment()) {
                            Log.d(TAG, "Permission " + bp.name + " is not a changeable permission type");
                            continue;
                        }
                        sGrantPermissionSet.add(permission);
                     }
                 }
                 Log.d(TAG, " need grantRuntimePermission size:"+sGrantPermissionSet.size());
                 for (String permission : sGrantPermissionSet) {
                    mPackageManager.grantRuntimePermission(pkgName,
                            permission, Process.myUserHandle());
                 }
                 if (checkInstallPackagesPermission(pkgName, mPackageInfo)) {
                     Log.e(TAG, pkgName + " need grant INSTALL_PACKAGES permission");
                     mAppOpsManager.setMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
                        mPackageInfo.applicationInfo.uid, pkgName, AppOpsManager.MODE_ALLOWED);
                     Log.e(TAG, "grant INSTALL_PACKAGES permission done");
                 }
            } catch (Exception e) {
                //e.printStackTrace();
                Log.d(TAG, e.getMessage());
            }
        }
    }
    private static boolean checkInstallPackagesPermission(String packageName, PackageInfo mPackageInfo){
        int uid = mPackageInfo.applicationInfo.uid;
        //boolean permissionGranted = hasPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES, uid);
        boolean permissionRequested = hasRequestedAppOpPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES, packageName);
        int appOpMode = getAppOpMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, uid, packageName);
        return appOpMode != AppOpsManager.MODE_DEFAULT || permissionRequested;
    }
    private static int getAppOpMode(int appOpCode, int uid, String packageName) {
        return mAppOpsManager.checkOpNoThrow(appOpCode, uid, packageName);
    }
    private static boolean hasRequestedAppOpPermission(String permission, String packageName) {
        try {
            String[] packages = mIpm.getAppOpPermissionPackages(permission);
            return ArrayUtils.contains(packages, packageName);
        } catch (Exception exc) {
            Log.e(TAG, "PackageManager dead. Cannot get permission info");
            return false;
        }
    }
    private static boolean hasPermission(String permission, int uid) {
        try {
            int result = mIpm.checkUidPermission(permission, uid);
            return result == PackageManager.PERMISSION_GRANTED;
        } catch (Exception e) {
            Log.e(TAG, "PackageManager dead. Cannot get permission info");
            return false;
        }
    }
    /**
     * Get removable system app list from config file
     *
     * @param resultSet
     *            Returned result list
     * @param file
     *            The config file
     */
    private static void sGetGrantSystemAppFromFile(
            HashSet<String> resultSet, File file) {
        resultSet.clear();
        FileReader fr = null;
        BufferedReader br = null;
        try {
            if (file.exists()) {
                fr = new FileReader(file);
            } else {
                Log.d(TAG, "file in " + file + " does not exist!");
                return;
            }
            br = new BufferedReader(fr);
            String line;
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if (!TextUtils.isEmpty(line)) {
                    Log.d(TAG, "read line " + line);
                    resultSet.add(line);
                }
            }
            Log.e(TAG,"GRANT_SYS_APP_LIST_SYSTEM size="+resultSet.size());
        } catch (Exception io) {
            Log.d(TAG, io.getMessage());
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (fr != null) {
                    fr.close();
                }
            } catch (IOException io) {
                Log.d(TAG, io.getMessage());
            }
        }
    }
}


目录
相关文章
|
9月前
|
存储 前端开发 API
可配置化App启动弹窗系统:实现后台动态管理与热更新引导-蜻蜓Q系统laravel+vue3-优雅草卓伊凡
可配置化App启动弹窗系统:实现后台动态管理与热更新引导-蜻蜓Q系统laravel+vue3-优雅草卓伊凡
483 5
可配置化App启动弹窗系统:实现后台动态管理与热更新引导-蜻蜓Q系统laravel+vue3-优雅草卓伊凡
|
9月前
|
Linux 测试技术 语音技术
【车载Android】模拟Android系统的高负载环境
本文介绍如何将Linux压力测试工具Stress移植到Android系统,用于模拟高负载环境下的CPU、内存、IO和磁盘压力,帮助开发者优化车载Android应用在多任务并发时的性能问题,提升系统稳定性与用户体验。
741 6
|
9月前
|
存储 前端开发 安全
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
357 5
|
9月前
|
Java 数据库 Android开发
基于Android的电子记账本系统
本项目研究开发一款基于Java与Android平台的开源电子记账系统,采用SQLite数据库和Gradle工具,实现高效、安全、便捷的个人财务管理,顺应数字化转型趋势。
|
10月前
|
缓存 小程序 开发工具
最新原创uniapp+vue3仿微信界面聊天app系统
最新原创研发uniapp+vue3实战跨端仿微信App界面聊天程序。支持运行到H5+小程序+APP端。
430 6
最新原创uniapp+vue3仿微信界面聊天app系统
|
10月前
|
缓存 小程序 iOS开发
基于uni-app+vue3手机桌面oadmin管理系统
基于uniapp+vue3+pinia2+uv-ui仿ios手机界面oa后台系统解决方案。支持运行到h5+小程序+app端。
514 5
|
11月前
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
1305 4
|
10月前
|
安全 测试技术 虚拟化
Omnissa App Volumes 4, version 2506 - 实时应用程序交付系统
Omnissa App Volumes 4, version 2506 - 实时应用程序交付系统
188 0
|
12月前
|
消息中间件 缓存 小程序
婚恋交友相亲公众号app小程序系统源码「脱单神器」婚恋平台全套代码 - 支持快速二次开发
这是一套基于SpringBoot + Vue3开发的婚恋交友系统,支持微信公众号、Uniapp小程序和APP端。系统包含实名认证、智能匹配、视频相亲、会员体系等功能,适用于婚恋社交平台和相亲交友应用。后端采用SpringBoot 3.x与MyBatis-Plus,前端使用Vue3与Uniapp,支持快速部署和二次开发。适合技术团队或有经验的个人创业者使用。
845 8
|
11月前
|
小程序 Java 关系型数据库
圈子系统公众号app小程序系统源码圈子系统带即时通讯 多级圈子系统源码 兴趣小组系统开源 私密圈子系统代码 会员制社区系统
本圈子系统解决方案提供即时通讯、多级圈子、兴趣小组、私密社区及会员制管理功能。支持开源与商业方案,推荐ThinkSNS+、EasyClub及OpenFire等系统,并提供前后端技术选型建议,助力快速搭建社交平台。
594 0

热门文章

最新文章