现象 not in privapp-permissions whitelist
01-01 05:31:20.783 776-776/? W/PackageManager: Privileged permission android.permission.WRITE_SECURE_SETTINGS for package com.android.lava.powersave - not in privapp-permissions whitelist
01-01 05:31:20.784 776-776/? W/PackageManager: Privileged permission android.permission.FORCE_STOP_PACKAGES for package com.android.lava.powersave - not in privapp-permissions whitelist
01-01 05:31:20.784 776-776/? W/PackageManager: Privileged permission android.permission.MEDIA_CONTENT_CONTROL for package com.android.lava.powersave - not in privapp-permissions whitelist
01-01 05:31:20.785 776-776/? W/PackageManager: Privileged permission android.permission.INTERACT_ACROSS_USERS for package com.android.lava.powersave - not in privapp-permissions whitelist
01-01 05:31:20.785 776-776/? W/PackageManager: Privileged permission android.permission.MANAGE_USERS for package com.android.lava.powersave - not in privapp-permissions whitelist
01-01 05:31:20.785 776-776/? W/PackageManager: Privileged permission android.permission.SHUTDOWN for package com.android.lava.powersave - not in privapp-permissions whitelist
01-01 05:31:27.707 776-966/? W/PackageManager: Privileged permission android.permission.INTERACT_ACROSS_USERS for package com.lava.led - not in privapp-permissions whitelist
具体原因源代码
找到问题的原因很关键,以下是SourceInsight的记录
// SourceInsight的记录
PackageManagerService.java (base\services\core\java\com\android\server\pm): + pkg.packageName + " - not in privapp-permissions whitelist");
// 具体源码
private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
BasePermission bp, PermissionsState origPermissions) {
boolean privilegedPermission = (bp.protectionLevel
& PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
boolean privappPermissionsDisable =
RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
&& !platformPackage && platformPermission) {
ArraySet<String> wlPermissions = SystemConfig.getInstance()
.getPrivAppPermissions(pkg.packageName);
boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
if (!whitelisted) {
Slog.w(TAG, "Privileged permission " + perm + " for package "
+ pkg.packageName + " - not in privapp-permissions whitelist");
查看源码我们发现数组wlPermissions有无白名单是关键,故接下来的操作就是找到添加白名单的位置即可
白名单的读取路径
对 ArraySet wlPermissions = SystemConfig.getInstance() .getPrivAppPermissions(pkg.packageName);进行一层一层往上找
以下是添加白名单的代码片段
void readPrivAppPermissions(XmlPullParser parser) throws IOException, XmlPullParserException {
String packageName = parser.getAttributeValue(null, "package");
if (TextUtils.isEmpty(packageName)) {
Slog.w(TAG, "package is required for <privapp-permissions> in "
+ parser.getPositionDescription());
return;
}
ArraySet<String> permissions = mPrivAppPermissions.get(packageName);
if (permissions == null) {
permissions = new ArraySet<>();
}
int depth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, depth)) {
String name = parser.getName();
if ("permission".equals(name)) {
String permName = parser.getAttributeValue(null, "name");
if (TextUtils.isEmpty(permName)) {
Slog.w(TAG, "name is required for <permission> in "
+ parser.getPositionDescription());
continue;
}
permissions.add(permName);
}
}
mPrivAppPermissions.put(packageName, permissions);
}
故上述中XmlPullParser parser是数据源的位置
具体核心代码如下
void readPermissions(File libraryDir, int permissionFlag) {
// Read permissions from given directory.
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
if (permissionFlag == ALLOW_ALL) {
Slog.w(TAG, "No directory " + libraryDir + ", skipping");
}
return;
}
if (!libraryDir.canRead()) {
Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
return;
}
// Iterate over the files in the directory and scan .xml files
File platformFile = null;
for (File f : libraryDir.listFiles()) {
// We'll read platform.xml last
if (f.getPath().endsWith("etc/permissions/platform.xml")) {
platformFile = f;
continue;
}
if (!f.getPath().endsWith(".xml")) {
Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
continue;
}
if (!f.canRead()) {
Slog.w(TAG, "Permissions library file " + f + " cannot be read");
continue;
}
// 读取位置 1
readPermissionsFromXml(f, permissionFlag);
}
// Read platform permissions last so it will take precedence
if (platformFile != null) {
// 读取位置 2
readPermissionsFromXml(platformFile, permissionFlag);
}
}
通过上面的代码片段我们得到了以下路径
/vendor/etc/permissions/platform.xml
/odm/etc/permissions/platform.xml
很可惜 读取位置1 /vendor/etc/permissions /中并没有platform.xml
iris53:/vendor/etc/permissions # ls
ls
android.hardware.audio.low_latency.xml
android.hardware.bluetooth.xml
android.hardware.bluetooth_le.xml
android.hardware.camera.xml
android.hardware.faketouch.xml
android.hardware.location.gps.xml
android.hardware.microphone.xml
android.hardware.sensor.accelerometer.xml
android.hardware.sensor.light.xml
android.hardware.sensor.proximity.xml
android.hardware.telephony.gsm.xml
android.hardware.touchscreen.multitouch.distinct.xml
android.hardware.touchscreen.multitouch.jazzhand.xml
android.hardware.touchscreen.multitouch.xml
android.hardware.touchscreen.xml
android.hardware.usb.accessory.xml
android.hardware.usb.host.xml
android.hardware.wifi.direct.xml
android.hardware.wifi.xml
android.software.live_wallpaper.xml
android.software.midi.xml
handheld_core_hardware.xml
故我们只能看下根目录文件是否存在etc/permissions/platform.xml
iris53:/etc/permissions # ls
ls
android.software.live_wallpaper.xml com.google.android.media.effects.xml
android.software.webview.xml mediatek-packages-teleservice.xml
com.android.location.provider.xml platform.xml
com.android.media.remotedisplay.xml privapp-permissions-google.xml
com.android.mediadrm.signer.xml privapp-permissions-mediatek.xml
com.google.android.maps.xml privapp-permissions-platform.xml
上述通过名称我们发现privapp-permissions-platform.xml更为接近
解决方案
找到源代码对应的xml文件,这里可以framework下直接搜索 find ./ -name “platform.xml”
搜索结果如下
./system/etc/permissions/platform.xml
打开privapp-permissions-platform.xml文件,添加如下
<!-- Lava privapp-permissions whitelist -->
<privapp-permissions package="com.android.lava.powersave">
<permission name="android.permission.WRITE_SECURE_SETTINGS" />
<permission name="android.permission.FORCE_STOP_PACKAGES" />
<permission name="android.permission.MEDIA_CONTENT_CONTROL" />
<permission name="android.permission.INTERACT_ACROSS_USERS" />
<permission name="android.permission.MANAGE_USERS" />
<permission name="android.permission.SHUTDOWN" />
<permission name="android.permission.INTERACT_ACROSS_USERS" />
</privapp-permissions>
重新编译烧录即可,消除这个警告