【笔记】PKMS 预置第三方应用可卸载

1.原始方案:

1.创建 “/system/third_app”文件夹

2. 预置第三方APP的Android.mk 中 LOCAL_MODULE_PATH = “/system/third_app”

3. PKMS 源码中添加 copy 代码:

    (1): isFirstBoot() 判断第一次开机之后;

    (2):scanDirLI() 扫描app之前

    (3): copy 的路径是 “/system/third_app” ---> "/data/app"

              ----:question : PKMS 扫描/system/app 和 /data/app 下的应用的区别在于调用scaDirLI()时,/system/app 会传下去“PackageParser.PARSE_IS_SYSTEM”  的parseFlag 而/data/app 传下去的parseFlag 是null

             -----: 直接调用FileUtils.copyFile 进行copy

缺点:

1.copy到data/app下会有两份apk,占空间;

2.采用异步copy ,如果很大的apk ,则调用到扫描/data/app时 ,还没copy 完成;

优点:

1.恢复出场设置后,third_app 是在/system 下的,仍然会扫描重新安装

 

*优化思路*

1.PKMS 2 个成员变量

       1.1 PKMS.mSettings :维护/data/system/package.xml 文件,最后扫描的结果存放在 PKMS.mSettings.mPackage<PackageSettings> 这个arrayList 数组中;

      1.2 PKMS.mPackages :维护记录当前PKMS 动态pkg 的信息,保存在PKMS.mPackages<PackageParser.package> 这个arrayList 数组中;

2. /system/app 或者/system/priv-app 为什么不可以被删除?

   因为 PKMS 调用scanDirLI 扫描“/system/app” 和 “/system/priv-app” 这两个路径时,下发了SYSTEM_APP的parserFlag,此flag表示此APP 为系统APP ,删除时会检查此flag,有此flag不可以删除;

3. 定制APP ,必须放在/system 下面:

    scanDirLI 时如果下发SYSTEM_APP,不能删除;

    scanDirLI 时如果不下发SYSTEM_APP,则生成的lib库文件 和dex 文件都在/system 路径下,要访问此路径,必须是system_app ,不然没有权限(APP 获取自己的数据存储路径,写的时候selinux denied)

4. lib ,dex 文件路径

  4.1 lib 库

   PKMS.scanDirLI -->PKMS.scanPackageDirtyLI()  --> PKMS.setNativeLibraryPaths() 函数确当lib 库路径 , 很重要的逻辑:如果扫描的是一个apk文件,就会pkg 的lib_path = /data/app-lib/<packagename>/lib , 如果传下去的是以“packagename”命名的文件夹,文件夹下有此pakcage,就会直接在“/system/app/<packagename>”下生成/lib/XXX.so 文件

 4.2 dex 文件

(预编译的问题 :

    1.正常情况是开机扫描,copy pkg 的dex 文件 到/data/dalvik-cache ----> 耗时;

    2.在BoardConfig.mk 中开启 WITH_DEXPREOPT := true 这个宏,会直接在/system/third_app/<packagename>/oat/  下生成dex 文件,然后进行拷贝到/data/dalvik-cache 时 selinux 异常 , 部分不拷贝到/data/dalvik 下面 ,  异常 ... ..

       解决方法: /system/third_app/ 下APP 的Android.mk 上 LOCAL_DEX_PREOPT = false

 PKMS.scanDirLI -->PKMS.scanPackageDirtyLI() -->PackageDexOptimizer.performDexOpt -->Installer -->Installd.dexopt ,逻辑和lib 库一样,传下去的是apk位置,就在/data/dalvik-cache/ 下 生成dex 文件;

5. PKMS 扫描/system/third_app时,传下去的是apk源文件的位置,而不是apk所在文件夹的位置 

     1.增加PKMS.mVendorSettings 负责维护/data/system/custom-packages.xml ,此文件记录所有PKMS维护的pkg 中标记为vendor 的pkg,存放在PKMS.mSettings<VendorPackageSettings>;

     2.增加PKMS.mVendorPackage<PackageParser.package>, 记录PKMS 中/system/third_app/下app 的信息

     3.PKMS 初始化时,scanDirLI “/system/third_app” 时 ,传下区的parserFlag = VendorPackage (在PackageParser.java 中添加) 

    4.PKMS 流程中,所有对mSetting.mPackages 和PKMS.mPackages 进行更新时,同时对mVendorSetting.mPackages 和PKMS.mVendorPackages 进行更新

6.删除apk 处理

   /system/third_app 下是非system app ,所以可以走正常的删除流程,但是:

  1.removePackageDataLI 函数中进行删除源文件时,检查Vendor_app 的flag ,如果是则不进行源文件的删除,删除lib库,oat文件 等等;

  2.PKMS.mVendorSetting.mVendorPackages<vendroPackageSetting> 对象中,mIntallStatus 变量设置为false ,表示被删除;

 3.PKMS.scanDirLI 扫描/system/third_app 时,监听mIntallStatus ,false 则不扫描;

 4. PKMS 扫描完会同步PKMS.mPackage  -> PKMS.mSettings -> /data/system/package.xml 上。

7.最后的结果

1./systen/third_app 中的apk 可以正常卸载;

2.恢复出场设置后,/system/third_app 重新安装;

*****

应用放在/system/third_app/<PackageName>/XXXX.apk

则扫描时 生成的lib库文件 和 dex 文件的路径就在/system/third_app/<PackageName>/lib/****   和   /system/third_app/<PackageName>/oat/****    都是在/system 下面,但是scanDirLI时  没有传SYSTEM_APP 的 parser_flag,所以系统不认为其为system_app ,这个app 的进程就无法访问/system 下的文件。

所以处理方法为,创建lib  和 dex 文件时,扫描的是直接为XXXX.apk 文件 ,而不是system/third_app/<PackageName>/ 这个目录,这样生成的lib 库 和 dex 文件 就不在/system 下 ,而是在/data 下

猜你喜欢

转载自blog.csdn.net/pirionFordring/article/details/83833587
今日推荐