Rockchip平台Android应用预安装功能(基于Android13)

Rockchip平台Android应用预安装功能(基于Android13)

1. 预安装应用类型

Android上的应用预安装功能,主要是指配置产品时,根据厂商要求,将事先准备好的第三方应用预置进Android系统。预安装分为以下几种类型:

  1. 安装不可卸载应用
  2. 安装可永久卸载应用
  3. 安装卸载后恢复出厂设置后自动恢复的应用

2. 功能启用说明

2.1 配置和使用

在进行以下操作之前,首先需要输入命令 get_build_var TARGET_DEVICE_DIR 来找到对应的目标文件夹(比如 device/rockchip/rk3126c/)。

在目标文件夹下有三个文件夹,分别为:

  1. preinstall
  2. preinstall_del_forever
  3. preinstall_del

请将需要预置的应用放入对应的文件夹,注意apk文件名尽量使用英文,避免空格。

顺利的话,执行make之后会在$OUT/oem目录生成对应的文件夹:

  1. bundled_persist-app
  2. bundled_uninstall_gone-app
  3. bundled_uninstall_back-app

仍旧对应概述中的几种类型。在烧录后,系统会自动安装这些应用到对应目录。

注意:不支持带systemuid应用的预制,请使用Android原生方式编写mk文件。可参考vendor/rockchip/common/apps/RkDeviceTest/的集成方式。

2.2 编译结果

编译后配置文件将会输出到odm分区($OUT/oem/),增加后请确认烧写了odm.img来使其生效。

3. 预编译脚本

预置应用编译脚本通过下面脚本完成

ifneq ($(strip $(TARGET_PRODUCT)), )$(shell python device/rockchip/common/auto_generator.py $(TARGET_DEVICE_DIR) preinstall bundled_persist-app $(TARGET_ARCH))$(shell python device/rockchip/common/auto_generator.py $(TARGET_DEVICE_DIR) preinstall_del bundled_uninstall_back-app $(TARGET_ARCH))$(shell python device/rockchip/common/auto_generator.py $(TARGET_DEVICE_DIR) preinstall_del_forever bundled_uninstall_gone-app $(TARGET_ARCH))-include $(TARGET_DEVICE_DIR)/preinstall/preinstall.mk-include $(TARGET_DEVICE_DIR)/preinstall_del/preinstall.mk-include $(TARGET_DEVICE_DIR)/preinstall_del_forever/preinstall.mk
endif

可以看到预置应用的Android.mk主要通过auto_generator.py完成

#!/usr/bin/env python
import sys
import os
import re
import zipfile
import shutil
import logging
import stringtemplet = """include $(CLEAR_VARS)
LOCAL_MODULE := %s
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/%s
LOCAL_SRC_FILES := $(LOCAL_MODULE)$(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_DEX_PREOPT := false
LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_JNI_SHARED_LIBRARIES_ABI := %s
MY_LOCAL_PREBUILT_JNI_LIBS := %s
MY_APP_LIB_PATH := $(TARGET_OUT_ODM)/%s/$(LOCAL_MODULE)/lib/$(LOCAL_JNI_SHARED_LIBRARIES_ABI)
ifneq ($(LOCAL_JNI_SHARED_LIBRARIES_ABI), None)
$(warning MY_APP_LIB_PATH=$(MY_APP_LIB_PATH))
LOCAL_POST_INSTALL_CMD := \mkdir -p $(MY_APP_LIB_PATH) \$(foreach lib, $(MY_LOCAL_PREBUILT_JNI_LIBS), ; cp -f $(LOCAL_PATH)/$(lib) $(MY_APP_LIB_PATH)/$(notdir $(lib)))
endif
include $(BUILD_PREBUILT)"""copy_app_templet = """LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_APK_NAME := %s
LOCAL_POST_PROCESS_COMMAND := $(shell mkdir -p $(TARGET_OUT_ODM)/%s/$(LOCAL_APK_NAME) && cp $(LOCAL_PATH)/$(LOCAL_APK_NAME).apk $(TARGET_OUT_ODM)/%s/$(LOCAL_APK_NAME)/)
"""def main(argv):preinstall_dir = os.path.join(argv[1],argv[2])if os.path.exists(preinstall_dir):#Use to include modulesisfound = 'not_found_lib'include_path = preinstall_dir + '/preinstall.mk'android_path = preinstall_dir + '/Android.mk'target_arch = argv[4]if os.path.exists(include_path):os.remove(include_path)if os.path.exists(android_path):os.remove(android_path)includefile = file(include_path, 'w')androidfile = file(android_path, 'w')androidfile.write("include $(call all-subdir-makefiles)\n\n")MY_LOCAL_PREBUILT_JNI_LIBS = '\\' + '\n'for root, dirs, files in os.walk(preinstall_dir):for file_name in files:p = re.compile(r'\S*(?=.apk\b)')found = p.search(file_name)if found:include_apk_path = preinstall_dir + '/' + found.group()makefile_path = include_apk_path + '/Android.mk'apk = preinstall_dir + '/' + found.group() + '.apk'try:zfile = zipfile.ZipFile(apk,'r')except:if os.path.exists(include_apk_path):shutil.rmtree(include_apk_path)os.makedirs(include_apk_path)apkpath = preinstall_dir + '/' + found.group() + '/'shutil.move(apk,apkpath)makefile = file(makefile_path,'w')makefile.write("LOCAL_PATH := $(my-dir)\n\n")makefile.write(templet % (found.group(),argv[3],'None',MY_LOCAL_PREBUILT_JNI_LIBS,argv[3]))continuefor lib_name in zfile.namelist():include_apklib_path = include_apk_path + '/lib' + '/arm'if os.path.exists(include_apk_path):shutil.rmtree(include_apk_path)os.makedirs(include_apklib_path)makefile = file(makefile_path,'w')makefile.write("LOCAL_PATH := $(my-dir)\n\n")apkpath = preinstall_dir + '/' + found.group() + '/'if target_arch == 'arm64':for lib_name in zfile.namelist():lib = re.compile(r'\A(lib/arm64-v8a/)+?')find_name = 'lib/arm64-v8a/'if lib_name.find(find_name) == -1:continuelibfound = lib.search(lib_name)if libfound:isfound = 'arm64-v8a'data = zfile.read(lib_name)string = lib_name.split(libfound.group())libfile = include_apklib_path + '/' + string[1]MY_LOCAL_PREBUILT_JNI_LIBS += '\t' + 'lib/arm64' + '/' + string[1] + '\\' + '\n'if (os.path.isdir(libfile)):continueelse:includelib = file(libfile, 'w')includelib.write(data)try:if cmp(isfound, 'not_found_lib'):include_apklib_path_arm64 = include_apk_path + '/lib/arm64'os.rename(include_apklib_path, include_apklib_path_arm64)except Exception as e:logging.warning('rename dir faild for:' + e)if not cmp(isfound,'not_found_lib'):for lib_name in zfile.namelist():lib = re.compile(r'\A(lib/armeabi-v7a/)+?')find_name = 'lib/armeabi-v7a/'#if not cmp(lib_name,find_name):#    continueif lib_name.find(find_name) == -1:continuelibfound = lib.search(lib_name)if libfound:isfound = 'armeabi-v7a'data = zfile.read(lib_name)string = lib_name.split(libfound.group())libfile = include_apklib_path + '/' + string[1]MY_LOCAL_PREBUILT_JNI_LIBS += '\t' + 'lib/arm' + '/' + string[1] + '\\' + '\n'if(os.path.isdir(libfile)):continueelse:includelib = file(libfile,'w')includelib.write(data)if not cmp(isfound,'not_found_lib'):for lib_name in zfile.namelist():lib = re.compile(r'\A(lib/armeabi/)+?')find_name = 'lib/armeabi/'#if not cmp(lib_name,find_name):#    continueif lib_name.find(find_name) == -1:continuelibfound = lib.search(lib_name)if libfound:data = zfile.read(lib_name)string = lib_name.split(libfound.group())libfile = include_apklib_path + '/' + string[1]MY_LOCAL_PREBUILT_JNI_LIBS += '\t' + 'lib/arm' + '/' + string[1] + '\\' + '\n'if(os.path.isdir(libfile)):continueelse:includelib = file(libfile,'w')includelib.write(data)tmp_jni_libs = '\\' + '\n'if not cmp(MY_LOCAL_PREBUILT_JNI_LIBS,tmp_jni_libs):nolibpath = preinstall_dir + '/' + found.group() + '/lib'shutil.rmtree(nolibpath)makefile.write(templet % (found.group(),argv[3],'None',MY_LOCAL_PREBUILT_JNI_LIBS,argv[3]))else:if isfound == 'arm64-v8a':makefile.write(templet % (found.group(),argv[3], 'arm64', MY_LOCAL_PREBUILT_JNI_LIBS,argv[3]))else:makefile.write(templet % (found.group(),argv[3],'arm',MY_LOCAL_PREBUILT_JNI_LIBS,argv[3]))shutil.move(apk,apkpath)isfound = 'not_found_lib'MY_LOCAL_PREBUILT_JNI_LIBS = '\\' + '\n'makefile.close()breakfor root, dirs,files in os.walk(preinstall_dir):for dir_file in dirs:includefile.write('PRODUCT_PACKAGES += %s\n' %dir_file)breakincludefile.close()if __name__=="__main__":main(sys.argv)

最终生成的Android.mk脚本如下:

LOCAL_PATH := $(my-dir)include $(CLEAR_VARS)
LOCAL_MODULE := MySysManager
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/bundled_persist-app
LOCAL_SRC_FILES := $(LOCAL_MODULE)$(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_DEX_PREOPT := false
LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_JNI_SHARED_LIBRARIES_ABI := None
MY_LOCAL_PREBUILT_JNI_LIBS := \MY_APP_LIB_PATH := $(TARGET_OUT_ODM)/bundled_persist-app/$(LOCAL_MODULE)/lib/$(LOCAL_JNI_SHARED_LIBRARIES_ABI)
ifneq ($(LOCAL_JNI_SHARED_LIBRARIES_ABI), None)
$(warning MY_APP_LIB_PATH=$(MY_APP_LIB_PATH))
LOCAL_POST_INSTALL_CMD :=     mkdir -p $(MY_APP_LIB_PATH)     $(foreach lib, $(MY_LOCAL_PREBUILT_JNI_LIBS), ; cp -f $(LOCAL_PATH)/$(lib) $(MY_APP_LIB_PATH)/$(notdir $(lib)))
endif
include $(BUILD_PREBUILT)

PackageManagerService对预安装应用的处理

//PackageManagerService.javapublic static final String BUNDLED_PERSIST_DIR = "/odm/bundled_persist-app";public static final String BUNDLED_UNINSTALL_GONE_DIR = "/odm/bundled_uninstall_gone-app";//Environment.java
private static final File DIR_PREBUNDLED_UNINSTALL_BACK_ROOT = getDirectory(ENV_PREBUNDLED_UNINSTALL_BACK_ROOT, "/odm/bundled_uninstall_back-app");private static final File DIR_PREBUNDLED_UNINSTALL_GONE_ROOT = getDirectory(ENV_PREBUNDLED_UNINSTALL_GONE_ROOT, "/odm/bundled_uninstall_gone-app");//InitAppsHelper.javapublic void preinstallThirdPartyAPK(PackageParser2 packageParser, ExecutorService executorService,int scanFlags){preinstallPrebundledpersist(packageParser,executorService,scanFlags);preinstallPrebundledUninstallBack(packageParser,executorService,scanFlags);preinstallPrebundledUninstallGone(packageParser,executorService,scanFlags);}private void preinstallPrebundledpersist(PackageParser2 packageParser, ExecutorService executorService,int scanFlags){scanDirTracedLI(new File(mPm.BUNDLED_PERSIST_DIR),null,mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR| ParsingPackageUtils.PARSE_IS_PREINSTALL,scanFlags | mPm.SCAN_AS_PREINSTALL| SCAN_AS_SYSTEM,packageParser, executorService);}private void preinstallPrebundledUninstallBack(PackageParser2 packageParser, ExecutorService executorService,int scanFlags){scanDirTracedLI(Environment.getPrebundledUninstallBackDirectory(),null,mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_IS_PREBUNDLED_DIR,scanFlags | mPm.SCAN_AS_PREBUNDLED_DIR,packageParser, executorService);}private void preinstallPrebundledUninstallGone(PackageParser2 packageParser, ExecutorService executorService,int scanFlags){scanDirTracedLI(Environment.getPrebundledUninstallGoneDirectory(),null,mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_IS_PREBUNDLED_DIR,scanFlags | mPm.SCAN_AS_PREBUNDLED_DIR,packageParser, executorService);}

需要进一步了解预安装应用相关流程,请查看preinstallPrebundled相关代码流程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/316463.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Vue3 前端构建工具》 Vue-cli 与 Vite 创建项目的插件和配置对比

前言 2024 年 啦!Vue2 也于 2023.12.31 寿终正寝 ! 然而我的 Vue3 升级一再拖延(惭愧不已)~ 赶起来吧~ 今天用 vue-cli 和 vite 分别创建了 Vue3 项目,具体实现步骤见如下两篇。 《基于 Vue Cli4.x Vue3 TS styl…

人工智能_机器学习087_DBSCAN聚类案例_聚类数据创建---人工智能工作笔记0127

之前我们把DBSCAN的原理以及参数都理解了,现在我们看如何使用 首先我们导包 import numpy as np 导入数学计算包 import matplotlib.pyplot as plt 导入画图包 from sklearn.cluster import KMeans,DBSCAN 导入算法 from sklearn import datasets 导入数据集包 X,y = data…

【IDEA——连接MySQL数据库,创建库和表】

IDEA——连接MySQL数据库,创建库和表 1、打开idea数据库操作页面(两种打开方法都可以) 2、点击加号,选择Driver,方便导入连接数据库的驱动jar包 然后选择MySQL进行添加驱动 3、点击上一步页面的左上方的Data Sources连接本地数据…

初始py和py开发工具

前言:上一章节给友友们讲解了如何安装py环境,这一章节就来练习一下如何写py的程序以及注意事项。 目录 一.你好世界 1.因为主播liunx用习惯的缘故所以所有的操作都在liunx上面执行,下面我们来看怎么写py的程序, 1.1首先打开liu…

【QT搭建】搭建可以生成手机APP的环境

一.问题分析 1.在原来的QT版本上安装Android(不推荐) 此方法暂时未实践成功,记录调试过程,可跳过 如果原来安装过QT桌面级PC软件的,可能没有配置JDK和SDK就会在QT选项的设备栏目种看到报错的提示。 并且Kits的选项里面没有Android,所以解决的问题是,缺少Kit套件Andro…

Qt(三):udp组播的发送与接收

1. 创建UDP套接字 使用QUdpSocket类创建一个UDP套接字。 udpSendnew QUdpSocket(this);udpRecenew QUdpSocket(this); 2. 绑定套接字 绑定套接字到一个本地地址和端口。可以使用bind()函数来完成。 如果要在组播中发送数据,可以将套接字绑定到一个通配符地址&#…

[GKCTF 2020]ez三剑客-eztypecho

[GKCTF 2020]ez三剑客-eztypecho 考点:Typecho反序列化漏洞 打开题目,发现是typecho的CMS 尝试跟着创建数据库发现不行,那么就搜搜此版本的相关信息发现存在反序列化漏洞 参考文章 跟着该文章分析来,首先找到install.php&#xf…

NSSCTF 1zjs

开启环境: 搞就完事了,别玩魔法! 源码打开 点击访问:./dist/index.umd.js" 搜索php,找到23条相关的,注意到有一个特别的信息: PERFORMANCE OF THIS SOFTWARE.Your gift just take it : /fk3f1ag.php 访问: node4.anna.nssctf.cn:28325/fk3f1ag.php 得到这样: ([![]…

JS中indexOf()方法的使用

在工作中 , indexOf() 方法使用频率还是非常高的,对于这个知识点,我们来做个简单的总结 基本定义:indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置,如果没有找到返回-1 - indexOf() 只返回字符串在规定的查找顺…

58.网游逆向分析与插件开发-游戏增加自动化助手接口-游戏菜单文字资源读取的逆向分析

内容来源于:易道云信息技术研究院VIP课 之前的内容:接管游戏的自动药水设定功能-CSDN博客 码云地址(master分支):https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号:34b9c1d43b512d0b4a3c395b…

最小二乘法解线性回归

最小二乘法 算法介绍 基于均方误差最小化来进行模型求解的方法称为“最小二乘法(least square method)它的主要思想就是选择未知参数,(a5,b5)(a3,b3)(a1,b1)(a4,b4)(a2,b2)使得理论值与观测值之差的平方和…

大数据平台Bug Bash大扫除最佳实践

一、背景 随着越来越多的"新人"在日常工作以及大促备战中担当大任,我们发现仅了解自身系统业务已不能满足日常系统开发运维需求。为此,大数据平台部门组织了一次Bug Bash活动,既能提升自己对兄弟产品的理解和使用,又能…