按照以往经验修改给三方apk权限全开,发现13上坑不少。PermissionController 仅仅只是一个普通app,就和在AS中直接编写一样,完全用不了一些hide api,尝试修改了几次 android.bp 文件没有任何效果,引入核心api编译依旧报错。那只好曲线救国了,最终通过aidl方式搞定。
修改清单
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
@@ -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
@@ -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
@@ -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
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
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
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
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
@@ -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
<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
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
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; } } }; }