按照以往经验修改给三方apk权限全开,发现13上坑不少。PermissionController 仅仅只是一个普通app,就和在AS中直接编写一样,完全用不了一些hide api,尝试修改了几次 android.bp 文件没有任何效果,引入核心api编译依旧报错。那只好曲线救国了,最终通过aidl方式搞定。
修改清单
java
frameworks/base/packages/PackageInstaller/Android.bp
frameworks/base/packages/PackageInstaller/AndroidManifest.xml
frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/IHEAppOpsManagerService.aidl
frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/HEAppOpsManagerService.java
frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
packages/modules/Permission/PermissionController/Android.bp
packages/modules/Permission/PermissionController/AndroidManifest.xml
packages/modules/Permission/PermissionController/src/com/android/packageinstaller/IHEAppOpsManagerService.aidl
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/PackageChangedService.java
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/PermissionGrantHelper.java
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/TemporaryFileManager.java
frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
java
@@ -789,8 +789,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
"updatePermissionFlags");
if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
- throw new SecurityException("updatePermissionFlags requires "
- + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
+ //cczheng annnotation for PermissionController app AppPermissionGroup.java:1280
+ /*throw new SecurityException("updatePermissionFlags requires "
+ + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);*/
}
packages/modules/Permission/PermissionController/Android.bp
java
@@ -82,7 +82,8 @@ android_app {
rename_resources_package: false,
required: ["privapp_allowlist_com.android.permissioncontroller.xml"],
- srcs: [":permissioncontroller-sources"],
+ srcs: [":permissioncontroller-sources",
+ "src/**/I*.aidl",],
libs: [
"android.car-stubs",
添加系统签名,为了在广播中直接启动服务
packages/modules/Permission/PermissionController/AndroidManifest.xml
java
@@ -6,7 +6,7 @@
coreApp="true"
android:versionCode="330000000"
android:versionName="33 system image"
->
+ android:sharedUserId="android.uid.system">
<original-package android:name="com.android.permissioncontroller" />
<!--cczheng add S -->
<receiver android:name="com.android.permissioncontroller.TemporaryFileManager"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="com.android.permissioncontroller.PackageChangedService"
android:exported="false"/>
<!--cczheng add E -->
packages/modules/Permission/PermissionController/src/com/android/packageinstaller/IHEAppOpsManagerService.aidl
java
package com.android.packageinstaller;
import android.content.pm.PackageInfo;
interface IHEAppOpsManagerService{
boolean checkInstallPackagesPermission(String packageName, in PackageInfo mPackageInfo);
}
监听apk安装替换、卸载、重装广播直接赋权
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/PackageChangedService.java
java
package com.android.permissioncontroller;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.net.Uri;
import android.os.SystemProperties;
import android.content.pm.PackageManager;
import java.util.ArrayList;
import java.util.List;
import java.io.File;
import android.content.pm.PackageInfo;
import android.content.ServiceConnection;
import android.content.ComponentName;
import com.android.packageinstaller.IHEAppOpsManagerService;
public class PackageChangedService extends Service {
private final String TAG = "permission";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate OK");
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand OK");
packageChangedBroadcastReceiver = new PackageChangedBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
intentFilter.addDataScheme("package");
registerReceiver(packageChangedBroadcastReceiver, intentFilter);
Intent aidlIntent = new Intent("com.hisense.permissioncontroller.IHEAppOpsManagerService");
aidlIntent.setPackage("com.android.packageinstaller");
bindService(aidlIntent, appOpsManagerConn, Context.BIND_AUTO_CREATE);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
try{
unregisterReceiver(packageChangedBroadcastReceiver);
unbindService(appOpsManagerConn);
}catch(Exception e){
e.printStackTrace();
}
super.onDestroy();
}
private IHEAppOpsManagerService mService = null;
ServiceConnection appOpsManagerConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected appOpsManagerConn");
mService = IHEAppOpsManagerService.Stub.asInterface(service);
}
};
private PackageChangedBroadcastReceiver packageChangedBroadcastReceiver;
private class PackageChangedBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
try{
String action = intent.getAction();
String packageName = intent.getData().getSchemeSpecificPart();
Log.e(TAG, "PackageChangedBroadcastReceiver action==" + action);
Log.i(TAG, "PackageChangedBroadcastReceiver packageName==" + packageName);
if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
PermissionGrantHelper.slientGrantRuntimePermission(mService, context, packageName);
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
} else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
Intent ccIntent = new Intent();
ccIntent.setAction("android.intent.action.MY_PACKAGE_REPLACED");
ccIntent.setData(Uri.parse("package:" + packageName));
ccIntent.addFlags(0x01000000);
context.sendBroadcast(ccIntent);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
引用不到相关api已经注释,采用aidl调用
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/PermissionGrantHelper.java
java
package com.android.permissioncontroller;
import android.content.Context;
import android.util.Log;
import android.content.pm.PackageInfo;
// import android.content.pm.IPackageManager;
import com.android.packageinstaller.IHEAppOpsManagerService;
import android.content.pm.PackageManager;
import com.android.permissioncontroller.permission.model.AppPermissionGroup;
import com.android.permissioncontroller.permission.model.AppPermissions;
import com.android.permissioncontroller.permission.model.Permission;
import com.android.permissioncontroller.permission.utils.ArrayUtils;
import com.android.permissioncontroller.permission.utils.Utils;
import java.util.List;
// import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.Manifest;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import static android.Manifest.permission.WRITE_SETTINGS;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
public class PermissionGrantHelper{
// private static IPackageManager mIpm;
private static AppOpsManager mAppOpsManager;
private static final String TAG = "PermissionGrantHelper";
public static void slientGrantRuntimePermission(IHEAppOpsManagerService mService, Context context, String packageName){
PackageInfo packageInfo;
try {
packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
} catch (PackageManager.NameNotFoundException e) {
Log.e("permission", "can't get PackageInfo for packageName="+ packageName);
return;
}
AppPermissions mAppPermissions = new AppPermissions(context, packageInfo, false, true,
new Runnable() {
@Override
public void run() {
}
});
// mIpm = AppGlobals.getPackageManager();
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
try{
if (mService.checkInstallPackagesPermission(packageName, packageInfo)) {
Log.e(TAG, packageName + " need grant INSTALL_PACKAGES permission");
mAppOpsManager.setMode(AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES/*OP_REQUEST_INSTALL_PACKAGES*/,
packageInfo.applicationInfo.uid, packageName, AppOpsManager.MODE_ALLOWED);
Log.e(TAG, "grant INSTALL_PACKAGES permission done");
}
}catch(Exception e){
e.printStackTrace();
}
if (checkAppOpsPermission(packageInfo, WRITE_SETTINGS)) {
Log.e(TAG, packageName + " need grant WRITE_SETTINGS permission");
//frameworks\proto_logging\stats\enums\app\enums.proto
mAppOpsManager.setMode(AppOpsManager.OPSTR_WRITE_SETTINGS/*AppOpsManager.OP_WRITE_SETTINGS*/,
packageInfo.applicationInfo.uid, packageName, AppOpsManager.MODE_ALLOWED);
Log.e(TAG, "grant WriteSetting permission done");
}
if (checkAppOpsPermission(packageInfo, SYSTEM_ALERT_WINDOW)) {
Log.e(TAG, packageName + " need grant SYSTEM_ALERT_WINDOW permission");
mAppOpsManager.setMode(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW/*AppOpsManager.OP_SYSTEM_ALERT_WINDOW*/,
packageInfo.applicationInfo.uid, packageName, AppOpsManager.MODE_ALLOWED);
Log.e(TAG, "grant SYSTEM_ALERT_WINDOW permission done");
}
Log.e("permission", " AppPermissionGroup size=="+mAppPermissions.getPermissionGroups().size());
if (mAppPermissions.getPermissionGroups().isEmpty()) {
Log.e("permission", "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);
if (!permission.isGranted()) {
permissionsToGrant = ArrayUtils.appendString(
permissionsToGrant, permission.getName());
Log.e("permission", "permissionName=" + permission.getName());
}
}
if (permissionsToGrant != null) {
group.grantRuntimePermissions(true, false, permissionsToGrant);
Log.i("permission", "grantRuntimePermissions permissionsToGrant");
//group.revokeRuntimePermissions(false);
}
//group.resetReviewRequired();
}
mAppPermissions.persistChanges(true);
}
//[E]
private static boolean checkAppOpsPermission(PackageInfo mPackageInfo, String permission){
for (int i = 0; i < mPackageInfo.requestedPermissions.length; i++) {
if (mPackageInfo.requestedPermissions[i].equals(permission)) {
return true;
}
}
return false;
}
}
开机广播启动服务
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/TemporaryFileManager.java
java
package com.android.permissioncontroller;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.util.Log;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import java.util.List;
import java.io.File;
import java.io.IOException;
public class TemporaryFileManager extends BroadcastReceiver {
private static final String LOG_TAG = TemporaryFileManager.class.getSimpleName();
@Override
public void onReceive(final Context context, Intent intent) {
Log.e("permission", "action==="+ intent.getAction());
context.startService(new Intent(context, PackageChangedService.class));
}
}
aidl服务端代码
frameworks/base/packages/PackageInstaller/Android.bp
java
@@ -35,7 +35,10 @@ android_app {
name: "PackageInstaller",
defaults: ["platform_app_defaults"],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ "src/**/I*.aidl",
+ ],
certificate: "platform",
privileged: true,
frameworks/base/packages/PackageInstaller/AndroidManifest.xml
java
<service android:name="com.android.packageinstaller.HEAppOpsManagerService"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="com.hisense.permissioncontroller.IHEAppOpsManagerService"/>
</intent-filter>
</service>
frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/IHEAppOpsManagerService.aidl
java
package com.android.packageinstaller;
import android.content.pm.PackageInfo;
interface IHEAppOpsManagerService{
boolean checkInstallPackagesPermission(String packageName, in PackageInfo mPackageInfo);
}
frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/HEAppOpsManagerService.java
java
package com.android.packageinstaller;
import android.app.Service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.Settings;
import android.util.Log;
import android.content.ContentResolver;
import android.text.TextUtils;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.app.AppGlobals;
import android.content.pm.PackageInfo;
import android.app.AppOpsManager;
import android.content.Context;
import android.Manifest;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import com.android.packageinstaller.IHEAppOpsManagerService;
public class HEAppOpsManagerService extends Service {
private static final String TAG = "HEAppOpsManagerService";
public static final boolean DEBUG = true;
@Override
public IBinder onBind(Intent arg0) {
IBinder iBinder = new HEAppOpsManagerServiceIml().asBinder();
if (iBinder == null) {
if (DEBUG)
Log.d(TAG, "iBinder null");
} else {
if (DEBUG)
Log.d(TAG, "iBinder ok");
}
return iBinder;
}
public class HEAppOpsManagerServiceIml extends IHEAppOpsManagerService.Stub {
private IPackageManager mIpm;
private AppOpsManager mAppOpsManager;
public HEAppOpsManagerServiceIml() {
mIpm = AppGlobals.getPackageManager();
mAppOpsManager = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE);
}
@Override
public boolean checkInstallPackagesPermission(String packageName, PackageInfo mPackageInfo)
throws RemoteException {
synchronized (HEAppOpsManagerServiceIml.class) {
boolean flag = checkInstallPermission(packageName, mPackageInfo);
Log.d(TAG,"packageName="+packageName+" need grant "+flag);
return flag;
}
}
private boolean checkInstallPermission(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 int getAppOpMode(int appOpCode, int uid, String packageName) {
return mAppOpsManager.checkOpNoThrow(appOpCode, uid, packageName);
}
private boolean hasRequestedAppOpPermission(String permission, String packageName) {
try {
String[] packages = mIpm.getAppOpPermissionPackages(permission);
return com.android.internal.util.ArrayUtils.contains(packages, packageName);
} catch (Exception exc) {
Log.e(TAG, "PackageManager dead. Cannot get permission info");
return false;
}
}
};
}