需求:
针对一些系统的应用或者第三方预置的应用,开机时默认授予权限,通知预置一个授权白名单文件,对文件内容的所有包名进行授权
预置授权文件
pms_sysapp_grant_permission_list.txt
com.gankao.gkwxhd
device/amlogic-o/u202/preinstall/preinstall.mk
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/files/pms_sysapp_grant_permission_list.txt:system/etc/permissions/pms_sysapp_grant_permission_list.txt
方案1 ,增加一个FunPackageManagerUtil 类,在PackageManagerService.java 启动的时候,启动默认授权
frameworks/base / services/core/java/com/android/server/pm/PackageManagerService.java
public void systemReady() {
// add for system app grant permission S
if (mFirstBoot) {
FunPackageManagerUtil.slientGrantRuntimePermission(mContext, mPermissionManager);
}
// add for system app grant permission E
}
frameworks/base/services/core/java/com/android/server/pm/FunPackageManagerUtil.java
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 com.android.server.pm.permission.BasePermission;
import com.android.server.pm.permission.PermissionManagerInternal;
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 FunPackageManagerUtil{
private static String TAG = "FunPackageManagerUtil";
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,
PermissionManagerInternal mPermissionManager){
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);
final BasePermission bp = (BasePermission) mPermissionManager.getPermissionTEMP(permission);
if (status != PackageManager.PERMISSION_GRANTED && bp != null) {
if (!bp.isRuntime() /*&& !bp.isDevelopment()*/) {
Log.d(TAG, "Permission " + bp.getName() + " is not a changeable permission type");
continue;
}
sGrantPermissionSet.add(permission);
}
}
Log.e(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());
}
}
}
}
方案2,在PackageInstaller 里面增加一个服务,进行授权
在AMS 中启动授权服务
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final void finishBooting() {
startPermisionService();
}
private void startPermisionService() {
try{
Log.d(TAG, "startPermisionService ...");
Intent intent = new Intent();
intent.setPackage("com.android.packageinstaller");
intent.setAction("android.permission.PackagePermissionGrantService");
mContext.startService(intent);
}catch (Exception e){
e.printStackTrace();
}
}
Background start not allowed
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
int getAppStartModeLocked() {
if(packageName.equalsIgnoreCase("com.android.packageinstaller")){
return ActivityManager.APP_START_MODE_NORMAL;
}
}
PackageInstaller/src/com/android/packageinstaller/permission/service/PackagePermissionGrantService.java
package com.android.packageinstaller.permission.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import android.os.Environment;
import com.android.packageinstaller.permission.model.AppPermissionGroup;
import com.android.packageinstaller.permission.model.AppPermissions;
import com.android.packageinstaller.permission.model.Permission;
import com.android.packageinstaller.permission.utils.ArrayUtils;
public class PackagePermissionGrantService extends Service {
private static final String TAG = "PackagePermission";
private static final File GRANT_SYS_APP_LIST_SYSTEM = new File(Environment.getRootDirectory(),"/etc/permissions/pms_sysapp_grant_permission_list.txt");
private static HashSet<String> sGrantSystemAppSet = new HashSet<String>();
Permissionhandler handler;
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate OK");
handler = new Permissionhandler();
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler.sendEmptyMessageDelayed(100,8000);
return Service.START_NOT_STICKY;
}
@Override
public void onDestroy() {
Log.e(TAG, " stop self onDestroy=");
handler.removeCallbacksAndMessages(null);
super.onDestroy();
}
class Permissionhandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 100:
Log.e(TAG, "start grant permission");
FunSlientGrantRuntimePermission();
sendEmptyMessageDelayed(101,15000);
break;
case 101:
stopSelf();
break;
}
}
}
public void FunSlientGrantRuntimePermission(){
sGetGrantSystemAppFromFile(sGrantSystemAppSet, GRANT_SYS_APP_LIST_SYSTEM);
Iterator<String> it = sGrantSystemAppSet.iterator();
while (it.hasNext()) {
String pkgName = it.next();
Log.d(TAG, "pkgName="+pkgName);
slientGrantRuntimePermission(pkgName);
}
}
public void slientGrantRuntimePermission(String packageName){
PackageInfo packageInfo;
try {
Log.e(TAG, "PackageInfo for packageName="+ packageName);
packageInfo = getPackageManager().getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "can't get PackageInfo for packageName="+ packageName);
return;
}
AppPermissions mAppPermissions = new AppPermissions(this, packageInfo, null, false,
new Runnable() {
@Override
public void run() {
stopSelf();
}
});
Log.e(TAG, " AppPermissionGroup size==" + mAppPermissions.getPermissionGroups().size());
if (mAppPermissions.getPermissionGroups().isEmpty()) {
Log.e(TAG, "mAppPermissions size isEmpty");
return;
}
for (AppPermissionGroup group : mAppPermissions.getPermissionGroups()) {
String[] permissionsToGrant = null;
final int permissionCount = group.getPermissions().size();
for (int j = 0; j < permissionCount; j++) {
final Permission permission = group.getPermissions().get(j);
Log.e(TAG, "permissionName=" +permission.getName()+",isGranted="+ permission.isGranted());
if (!permission.isGranted()) {
permissionsToGrant = ArrayUtils.appendString(
permissionsToGrant, permission.getName());
Log.e(TAG, "permissionName=" + permission.getName());
}
}
if (permissionsToGrant != null) {
group.grantRuntimePermissions(false, permissionsToGrant);
Log.i(TAG, "grantRuntimePermissions permissionsToGrant");
}
}
}
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());
}
}
}
}
AndroidManifest.xml
<service android:name="com.android.permissioncontroller.permission.service.PackagePermissionGrantService">
<intent-filter android:priority="1">
<action android:name="android.permission.PackagePermissionGrantService"/>
</intent-filter>
</service>