一、背景
- 当前OpenHarmony系统,给应用层提供的部分接口是系统接口,所谓系统接口就是只允许系统应用调用,不允许三方应用调用的接口。
- 那么这个只允许系统应用调用,这个限制到底是怎么落实到系统中的呢?
- 如何定义或者区分系统应用和三方应用呢?
二、探索
1、只允许系统应用调用
- 通过阅读源码,我们发现
BundleMgr
提供了一个方法CheckIsSystemAppByUid
,可以用来判断该应用是不是系统应用。起用法如下:- 首先我们要获取到
BundleMgr
实例,如下:
- 首先我们要获取到
static sptr<IBundleMgr> GetBundleMgr()
{
auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (sam == nullptr) {
USB_HILOGW(MODULE_USB_SERVICE, "GetSystemAbilityManager return nullptr");
return nullptr;
}
auto bundleMgrSa = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (bundleMgrSa == nullptr) {
USB_HILOGW(MODULE_USB_SERVICE, "GetSystemAbility return nullptr");
return nullptr;
}
auto bundleMgr = iface_cast<IBundleMgr>(bundleMgrSa);
if (bundleMgr == nullptr) {
USB_HILOGW(MODULE_USB_SERVICE, "iface_cast return nullptr");
}
return bundleMgr;
}
- 然后我们获取到调用当前系统接口的应用的
uid
,将该uid
传给CheckIsSystemAppByUid
来判断其是否是系统应用。
bool UsbRightManager::IsSystemHap()
{
pid_t uid = IPCSkeleton::GetCallingUid();
auto bundleMgr = GetBundleMgr();
if (bundleMgr == nullptr) {
USB_HILOGW(MODULE_USB_SERVICE, "BundleMgr is nullptr, return false");
return false;
}
return bundleMgr->CheckIsSystemAppByUid(uid);
}
- 这样我们就能知道调用我们接口的应用到底是不是系统应用。如果不是系统应用直接返回相应错误,不走正常业务逻辑,就能够达到我们的目的了。
2、制作一个普通应用
3、制作一个系统应用
- 首先需要说明下,OpenHarmony上系统应用和普通应用是通过签名来区分的,上面自动签名得到的是普通应用,所以我们想要得到系统应用就需要手动签名。官方签名教程在这里。
- 这里我写一个简易版教程(linux版本):
- 首先检查环境配置:
- 一键签名等脚本文件基于Python语言开发,使用需配置环境python3.x
java -version
如果没有安装,请自行安装。gradle -v
如果没有安装,可使用如下命令安装:mkdir /opt/gradle cd /opt/gradle wget -c https://services.gradle.org/distributions/gradle-7.1-bin.zip unzip gradle-7.1-bin.zip
- 将gadle的bin路径添加到环境变量中
export PATH=$PATH:/opt/gradle/gradle-7.1/bin
- 然后下载签名工具,将这个仓下载下来developtools_hapsigner
- 接着编译
hap-sign-tool.jar
,如下(选自官方教程):1、该工具基于Gradle 7.1编译构建,请确认环境已安装配置Gradle环境,并且版本正确 gradle -v 2、命令行打开文件目录至developtools_hapsigner/hapsigntool,执行命令进行编译打包 gradle build 或者 gradle jar 3、编译后得到二进制文件,目录为: ./hap_sign_tool/build/libs/hap-sign-tool.jar
- 修改
autosign/UnsgnedReleasedProfileTemplate.json
文件中的app-feature
值为ohos_system_app
,bundle-name
值为自己应用的包名,有些接口对apl要求较高,如有需要可将apl
值改为system_core
如下"apl": "system_core", "app-feature": "ohos_system_app"`
- 将待签名的应用命名为
app1-unsigned.hap
放到autosign/
目录下。 - 然后分别执行
create_appcert_sign_profile.sh
和sign_hap.sh
脚本,就会在目录developtools_hapsigner-master/autosign/result
下生成一个名为app1-signed.hap
的已签名的普通应用。
- 首先检查环境配置:
- 第二次签名的时候,有可能会报错。这种情况下,需要执行
git checkout autosign/result/OpenHarmony.p12
回退OpenHarmony.p12
文件的修改。然后再次执行create_appcert_sign_profile.sh
和sign_hap.sh
。后续签名只需要执行sign_hap.sh
。
三、总结
- 底层由BundleMgr提供了判断是否是三方应用的能力。
- 上层是否是系统应用取决于签名时的
app-feature
字段,如果是hos_normal_app
则为普通应用,是ohos_system_app
则为系统应用。
四、参考资料
1、deveco官方下载:https://developer.harmonyos.com/cn/develop/deveco-studio
2、OpenHarmony包签名工具:https://gitee.com/openharmony/developtools_hapsigner
3、gradle安装与使用:https://gradle.org/install/#manually