引言
平台信息:mt8788平台 android9.0
问题描述:安装讯飞输入法,重启机器,讯飞输入法消失
分析过程
安装apk后,adb shell进入机器,查看/data/app里面的文件
C:\Users\**\Desktop
$ adb shell
*****:/ # cd data/app
*****:/data/app # ls -l
total 4
drwxr-xr-x 4 system system 4096 2021-03-11 10:47 com.iflytek.inputmethod-aCAWRZAY6aKXH5TcK8RsCw==
*****:/data/app #
重启之后,/data/app里面文件消失。
众所周知,android系统开机时会启动PackageManagerService,去扫描特定目录下的apk,读取apk信息。
/data/data
/data/app
/data/app-lib
/data/user
/data/app-private
/vender/operater/app
话不多说,抓个开机log再说,过滤讯飞输入法包名com.iflytek.inputmethod
Line 119: 03-11 14:19:25.728 911 911 W PackageManager: System package com.iflytek.inputmethod no longer exists; it's data will be wiped
Line 121: 03-11 14:19:25.736 911 911 D PmsExtImpl: Skip scanning uninstalled sys package com.iflytek.inputmethod
Line 126: 03-11 14:19:25.741 911 911 W PackageManager: Removing dangling permission: app.custom.permission.GET_TTS_STATE from package com.iflytek.inputmethod
Line 143: 03-11 14:19:25.751 911 911 W PackageManager: Destroying /data/user/0/com.iflytek.inputmethod due to: com.android.server.pm.PackageManagerException: Package com.iflytek.inputmethod is unknown
Line 143: 03-11 14:19:25.751 911 911 W PackageManager: Destroying /data/user/0/com.iflytek.inputmethod due to: com.android.server.pm.PackageManagerException: Package com.iflytek.inputmethod is unknown
Line 144: 03-11 14:19:25.814 911 911 W PackageManager: Destroying /data/user_de/0/com.iflytek.inputmethod due to: com.android.server.pm.PackageManagerException: Package com.iflytek.inputmethod is unknown
Line 144: 03-11 14:19:25.814 911 911 W PackageManager: Destroying /data/user_de/0/com.iflytek.inputmethod due to: com.android.server.pm.PackageManagerException: Package com.iflytek.inputmethod is unknown
Line 483: 03-11 14:19:26.826 911 911 E RankingHelper: createDefaultChannelIfNeeded - Exception: android.content.pm.PackageManager$NameNotFoundException: com.iflytek.inputmethod
Line 732: 03-11 14:19:27.135 911 911 W PackageManager: Destroying orphaned/data/app/com.iflytek.inputmethod-aCAWRZAY6aKXH5TcK8RsCw==
Line 743: 03-11 14:19:27.156 911 911 I AppOps : Pruning old package com.iflytek.inputmethod/com.android.server.AppOpsService$UidState@29ba424: new uid=-1
来看看这段log,讯飞输入被擦除掉了
System package com.iflytek.inputmethod no longer exists; it's data will be wiped
根据log定位代码位置
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
..........
.........
final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
//判断是否为系统应用
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
// M版本:是否为可移除的app
if ((!sPmsExt.isRemovableSysApp(ps.name))) {
continue;
}
}
//如果扫描了这个package,则不会删除。这里为scannedPkg=null
final PackageParser.Package scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
//如果系统应用同时被扫描并且在禁用的软件包列表中,改应用必须通过OTA添加
//从当前扫描的程序包中删除它,以便可以扫描以前用户安装的应用程序
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
logCriticalInfo(Log.WARN,
"Expecting better updated system app for " + ps.name
+ "; removing system app. Last known"
+ " codePath=" + ps.codePathString
+ ", versionCode=" + ps.versionCode
+ "; scanned versionCode=" + scannedPkg.getLongVersionCode());
removePackageLI(scannedPkg, true);
mExpectingBetter.put(ps.name, ps.codePath);
}
continue;
}
if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
psit.remove();
//这里就是log打印出来的地方
logCriticalInfo(Log.WARN, "System package " + ps.name
+ " no longer exists; it's data will be wiped");
//实际删除代码和数据在后面的操作中
} else {
//有一个禁用的系统软件包,可能已经被删除。检查代码路径是否存在,检查安装包是否存在。
//如果OTA保持相同的代码路径,但是更改了程序包名称,则可能发生后者。
final PackageSetting disabledPs =
mSettings.getDisabledSystemPkgLPr(ps.name);
if (disabledPs.codePath == null || !disabledPs.codePath.exists()
|| disabledPs.pkg == null) {
possiblyDeletedUpdatedSystemApps.add(ps.name);
}
}
}
.........
.........
}
从上往下依次分析,首先定位到sPmsExt.isRemovableSysApp(ps.name)
frameworks/base/services/core/java/com/mediatek/server/pm/PmsExt.java
public boolean isRemovableSysApp(String pkgName) {
return false;
}
找到PmsExt.java的继承者,定位到代码实现位置
vendor/mediatek/proprietary/frameworks/base/services/core/java/com/mediatek/server/pm/PmsExtImpl.java
@Override
public boolean isRemovableSysApp(String pkgName) {
boolean ret = false;
if (sRemovableSysAppEnabled) {
ret = sRemovableSystemAppSet.contains(pkgName);
}
return ret;
}
sRemovableSystemAppSet是一个集合,看看这个集合数据的初始化,找到文件路径
private static final File REMOVABLE_SYS_APP_LIST_VENDOR = Environment
.buildPath(Environment.getVendorDirectory(), "etc", "permissions",
"pms_sysapp_removable_vendor_list.txt");
打开这个文件一看,好家伙,里面果真有讯飞输入法包名,果断去掉讯飞输入法包名。
diff --git a/vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_vendor_list.txt b/vendor/mediatek/proprietary/frameworks/base/dindex 574d465..0ae0f92 100644
--- a/vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_vendor_list.txt
+++ b/vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_vendor_list.txt
@@ -1,3 +1,2 @@
com.mediatek.vnet
-com.iflytek.inputmethod
com.hugeland.cdsplus
再看看这个文件编译规则
/device/mediatek/common/device.mk
# Add for PMS support removable system app
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_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
mm之后,把编译生成的文件push到/vendor//etc/permissions//pms_sysapp_removable_vendor_list.txt
安装讯飞输入法,重启,输入法还在,问题解决。