继上篇海思android随笔之hippo数据交互文章,讲解如何客制化db
本篇是案例实战,调用流程原理请看上篇文章
文章目录
前言
提示:本文是基于海思android 9.0 tv系统进行分析的
年后一直忙着android 12的项目,没时间弄。最近利用空闲时间整理了出来,分享给各位看官。
1. 流程图
2. 代码详解
这里举例新增两个自定义数据,1个数据可以菜单复位掉,1个无法菜单复位
2.1. 客制化ini
2.1.1. 新增ini定义
Android/device/hisilicon/bigfish/hippo/include/hi_mw_common.h
static const HI_CHAR* ATV_INI_TEST_INI_PATH = "atv/ini/test.ini";
2.1.2. 新建ini文件
Android/device/hisilicon/bigfish/hippo/vendor/custom/hisilicon/ini/CUSTOM/test.ini
[iniversion]
VerNumber = 1;
[databasedef]
DatabaseTestVersion = 0x0006;
test_one = 5;
test_two = 55;
2.1.3. 修改mk文件
Android/device/hisilicon/bigfish/hippo/hippo_copyfile.mak
PRODUCT_COPY_FILES += $(HISI_HIPPO_DIR)/vendor/custom/hisilicon/ini/CUSTOM/test.ini:atv/ini/test.ini
提示:这里copy的路径视项目而定,hisi AN9一般是copy到/atv/ini下,AN10以后改在了/odm/atv/ini下
2.1.4. 初始化ini
Android/device/hisilicon/bigfish/hippo/vendor/common/config/iniprovider/hi_mw_ini_provider.cpp
HI_VOID INIProvider::LoadIniFile()
{
******
iniPath = hi_get_one_cfg_file(ATV_INI_TEST_INI_PATH, CUST_TYPE_CONFIG, filePath);
LOGI("hi_get_one_cfg_file. testIniPath:%s", iniPath);
if ((iniPath == HI_NULL) || (strlen(filePath) > PATH_MAX)) {
LOGI("hi_get_one_cfg_file failed. %s", filePath);
return;
}
mIniPathVec.push_back(string(iniPath));
******
}
2.2. 客制化db
2.2.1. 新增db配置
Android/device/hisilicon/bigfish/hippo/vendor/custom/hisilicon/ini/CUSTOM/cfg.ini
databasetest = /atv/db/test.db;
Android/device/hisilicon/bigfish/hippo/vendor/common/db/hi_mw_dbo.h
enum HI_MW_ATTR_E {
******
HI_MW_ATTR_TEST = 0x450,
HI_MW_ATTR_TEST_ONE = 0x451,
HI_MW_ATTR_TEST_TWO = 0x452,
HI_MW_ATTR_TEST_END,
HI_MW_ATTR_BUTT = 0x500,
};
enum HI_MW_DB_E {
******
HI_MW_DB_TEST = HI_MW_ATTR_TEST,
HI_MW_DB_BUTT = HI_MW_ATTR_BUTT
};
2.2.2. 初始化db
Android/device/hisilicon/bigfish/hippo/vendor/common/db/hi_mw_dbo.h
class HiDBO {
public:
******
HI_VOID RestoreTest(HI_BOOL bMenuReset);
private:
******
}
Android/device/hisilicon/bigfish/hippo/vendor/common/db/hi_mw_dbo.cpp
static HI_VOID InsertTestDefault(HiDBO* pDbo, HiDB* pDb, HI_BOOL bMenuReset)
{
if((HI_NULL == pDbo) || (HI_NULL == pDb))
{
LOGE("pDbo or pDb is null !");
return;
}
pDb->CreateRecord(HI_MW_ATTR_TEST_ONE);
HI_U32 testOne = 0;
updateTestOne(testOne);
pDb->Insert(HI_MW_ATTR_TEST_ONE, (HI_U8*)&testOne, sizeof(testOne));
pDbo->Attach(HI_MW_ATTR_TEST_ONE, pDb);
if (bMenuReset == HI_FALSE) {
pDb->CreateRecord(HI_MW_ATTR_TEST_TWO);
HI_U32 testTwo = 0;
updateTestTwo(testTwo);
pDb->Insert(HI_MW_ATTR_TEST_TWO, (HI_U8*)&testTwo, sizeof(testTwo));
pDbo->Attach(HI_MW_ATTR_TEST_TWO, pDb);
}
LOGD("insert CVTE default data done.");
}
static HI_S32 LoadTestSetting(HiDBO * pDbo)
{
string dbFile = HiCfgFact::Get()->ParseString("databasepath:databasetest");
HI_U16 u16TestVersion = (HI_U16)HiCfgFact::Get()->ParseInt("databasedef:DatabaseTestVersion");
HI_S32 s32Ret;
HiDB *db = HI_NULL;
s32Ret = CreateFile(dbFile, &db);
if (s32Ret != HI_SUCCESS) {
return s32Ret;
}
HI_U16 u16Version = 0;
HI_BOOL bRestoreDefault = HI_FALSE;
s32Ret = db->QueryVersion(u16Version);
if (s32Ret == HI_MW_DB_FIRSTBOOT_EER) {
bRestoreDefault = HI_TRUE;
} else {
if (u16Version != u16TestVersion) {
LOGI("Update data version!");
db->Clear();
bRestoreDefault = HI_TRUE;
}
}
if (bRestoreDefault == HI_FALSE) {
HI_S32 s32Ret = db->Load();
if (s32Ret == HI_SUCCESS) {
list<HI_U32> records;
list<HI_U32>::iterator it;
db->GetRecords(records);
if (records.size() < (HI_MW_ATTR_TEST_END - HI_MW_ATTR_TEST - 1)) {
LOGI("Record is lose [%d, %d]!", records.size(), (HI_MW_ATTR_TEST_END - HI_MW_ATTR_TEST - 1));
} else {
for (it = records.begin(); it != records.end(); ++it) {
pDbo->Attach((HI_MW_ATTR_E)*it, db);
}
}
LOGI("load Test Setting data success!");
return HI_SUCCESS;
}
LOGI("Load data fail!");
db->Clear();
}
LOGI("Insert default data!");
db->InsertVersion(u16TestVersion);
InsertTestDefault(pDbo, db, HI_FALSE);
return HI_SUCCESS;
}
HI_VOID HiDBO::RestoreTest(HI_BOOL bMenuReset)
{
HiDB* db = NULL;
if (!Obtain(HI_MW_DB_TEST, &db) && (NULL != db))
{
if (bMenuReset) {
db->Erase(HI_MW_ATTR_TEST_ONE);
} else {
db->Clear();
}
db->InsertVersion(HiCfgFact::Get()->ParseInt("databasedef:DatabaseTestVersion"));
InsertTestDefault(this, db, bMenuReset);
LOGD("restore Test data success.");
}
}
******
HiDBO::HiDBO()
{
******
ret = LoadTestSetting(this);
RET_CHECK_ERR_LOG(ret, "LoadTestSetting failure.ret: 0x%x", ret);
******
}
******
Android/device/hisilicon/bigfish/hippo/vendor/common/db/hi_mw_db_def.h
HI_VOID updateTestOne(HI_U32 & value);
HI_VOID updateTestTwo(HI_U32 & value);
Android/device/hisilicon/bigfish/hippo/vendor/common/db/hi_mw_db_def.cpp
HI_VOID RestoreDbAttrSubEightPartB(HI_U32 u32Id, HI_U8 *pData, HI_MW_SRC_E &enSource)
{
******
switch (u32Id >> ATTR_BW) {
******
case HI_MW_ATTR_TEST_ONE:
{
HI_U32 testOne = 0;
updateTestOne(testOne);
memcpy(pData, &testOne, sizeof(testOne));
break;
}
case HI_MW_ATTR_TEST_TWO:
{
HI_U32 testTwo = 0;
updateTestTwo(testTwo);
memcpy(pData, &testTwo, sizeof(testTwo));
break;
}
******
}
******
}
HI_VOID GetLengthFromIDSubSix(HI_U32 u32Id, HI_U32 &u32Length)
{
switch (u32Id) {
******
case HI_MW_ATTR_TEST_ONE:
case HI_MW_ATTR_TEST_TWO:
u32Length = sizeof(HI_U32);
break;
******
}
}
HI_VOID updateTestOne(HI_U32 & value)
{
value = HiCfgFact::Get()->ParseInt("databasedef:test_one");
}
HI_VOID updateTestTwo(HI_U32 & value)
{
value = HiCfgFact::Get()->ParseInt("databasedef:test_two");
}
2.2.3. 完善hippo接口
Android/device/hisilicon/bigfish/hippo/vendor/adapter/hi_tv_instruct.h
enum ATV_CMD_ID_E {
******
CMD_SYSTEM_RESTORETEST = 0x8040,
CMD_SYSTEM_SETTEST = 0x8041,
CMD_SYSTEM_GETTEST = 0x8042,
******
}
Android/device/hisilicon/bigfish/hippo/vendor/logic/module_api/hi_mw_logic_system_module.cpp
static HI_S32 RestoreTest(const Parcel &in, Parcel &out)
{
HI_BOOL bMenuReset = (HI_BOOL)in.readInt32();
HI_S32 ret = HiSystem::instance()->RestoreTest(bMenuReset);
LOGI("bMenuReset:%d, ret:%d", bMenuReset, ret);
return ret;
}
static HI_S32 SetTest(const Parcel &in, Parcel &out)
{
HI_U32 u32Type;
HI_U32 u32Value;
u32Type = (HI_U32)in.readInt32();
u32Value = (HI_U32)in.readInt32();
HI_S32 ret = HiSystem::instance()->SetTest(u32Type, u32Value);
LOGI("SetTest to DB, type:%d, value = %d, ret:%d", u32Type, u32Value, ret);
return ret;
}
static HI_S32 GetTest(const Parcel &in, Parcel &out)
{
HI_U32 u32Type;
HI_U32 u32Value;
u32Type = (HI_U32)in.readInt32();
HI_S32 ret = HiSystem::instance()->GetTest(u32Type, &u32Value);
out.writeInt32(u32Value);
LOGI("GetTest from DB, type:%d, value = %d, ret:%d", u32Type, u32Value, ret);
return ret;
}
static LocalAtomicInfo g_astSystemModuleLocalAtomicInfo[] = {
******
{ CMD_SYSTEM_RESTORETEST, RestoreTest },
{ CMD_SYSTEM_SETTEST, SetTest },
{ CMD_SYSTEM_GETTEST, GetTest },
}
Android/device/hisilicon/bigfish/hippo/vendor/logic/include/hi_mw_logic_system.h
class HiSystem : public HiMWThread {
public:
******
HI_S32 RestoreTest(HI_BOOL bMenuReset);
HI_S32 SetTest(HI_U32 type, HI_U32 value);
HI_S32 GetTest(HI_U32 type, HI_U32 *value);
private:
******
};
Android/device/hisilicon/bigfish/hippo/vendor/logic/setting/hi_mw_logic_system.cpp
HI_S32 HiSystem::RestoreTest(HI_BOOL bMenuReset)
{
HiDBOFact::GetDBO()->RestoreTest(bMenuReset);
LOGI("HiSystem::RestoreTest:%d", bMenuReset);
return HI_SUCCESS;
}
HI_S32 HiSystem::SetTest(HI_U32 type, HI_U32 value)
{
HI_U32 tmp = value;
switch(type) {
case 1:
HiDBOFact::GetDBO()->Update(HI_MW_ATTR_TEST_ONE, (HI_U8 *)&tmp, sizeof(HI_U32));
break;
case 2:
HiDBOFact::GetDBO()->Update(HI_MW_ATTR_TEST_TWO, (HI_U8 *)&tmp, sizeof(HI_U32));
break;
default:
break;
}
LOGI("HiSystem::SetTest type:%d value:%d tmp:%d", type, value, tmp);
return HI_SUCCESS;
}
HI_S32 HiSystem::GetTest(HI_U32 type, HI_U32 *value)
{
if (value == HI_NULL) {
LOGE("value is null ptr");
return HI_FAILURE;
}
switch(type) {
case 1:
HiDBOFact::GetDBO()->Query(HI_MW_ATTR_TEST_ONE, (HI_U8 *)value, sizeof(HI_U32));
break;
case 2:
HiDBOFact::GetDBO()->Query(HI_MW_ATTR_TEST_TWO, (HI_U8 *)value, sizeof(HI_U32));
break;
default:
break;
}
LOGI("HiSystem::GetTest type:%d value=%d", type, *value);
return HI_SUCCESS;
}
Android/device/hisilicon/bigfish/hippo/vendor/debug/hidebug/cmds.conf
[restoretest]
command = rst
belong module = system
instruction = 0x8040
para format = d
description = which way to reset test db data. eg: rst 1. [0:allreset 1:menureset]
[settest]
command = stest
belong module = system
instruction = 0x8041
para format = dd
description = set test one or two value. eg: stext 1 10. [1:test_one 2:test_two]
[gettest]
command = gtest
belong module = system
instruction = 0x8042
para format = d
print format = d
print tags = test one or two value
description = get test one or two value. eg: gtest 1. [1:test_one 2:test_two]
2.2.4. 完善jar包接口
Android/device/hisilicon/bigfish/hippo/api/java/com/hisilicon/android/tvapi/constant/EnumSystemCmd.java
public abstract class EnumSystemCmd {
******
public static final int CMD_SYSTEM_RESTORETEST = 0x8040;
public static final int CMD_SYSTEM_SETTEST = 0x8041;
public static final int CMD_SYSTEM_GETTEST = 0x8042;
******
}
Android/device/hisilicon/bigfish/hippo/api/java/com/hisilicon/android/tvapi/impl/SystemSettingImpl.java
******
public int RestoreTest(boolean bMenuReset) {
int ret = HitvManager.getInstance().excuteCommandSet(EnumSystemCmd.CMD_SYSTEM_RESTORETEST, bMenuReset ? 1 : 0);
HiMwLogTool.info(TAG, "RestoreTest, menureset:" + bMenuReset + retStatu(ret));
return ret;
}
public int SetTest(int type, int value) {
int ret = HitvManager.getInstance().excuteCommandSet(EnumSystemCmd.CMD_SYSTEM_SETTEST, type, value);
HiMwLogTool.info(TAG, "SetTest, type:" + type + " value:" + value + retStatu(ret));
return ret;
}
public int GetTest(int type) {
int ret = HitvManager.getInstance().excuteCommandGet(EnumSystemCmd.CMD_SYSTEM_GETTEST, type);
HiMwLogTool.info(TAG, "GetTest, type" + type + retStatu(ret));
return ret;
}
******
这里选择已经暴露给应用层的SystemSettingImpl实列,通过它调用对应CMD去实现功能。也可以使用海思其他实例,比如CusExImpl
3. 使用案例
3.1. hidebug
如图,依次执行命令,验证结果OK
3.2. appdebug
上面修改导入源码,编译后生成的新jar包,路径是
Android\out\target\common\obj\JAVA_LIBRARIES\HiDtvShare_intermediates\classes.jar
app导入jar包,调用接口
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.buttonSetting:
Log.d("mzhe", "click button getall");
Log.d("mzhe", "test one = " + SystemSettingImpl.getInstance().GetTest(1));
Log.d("mzhe", "test two = " + SystemSettingImpl.getInstance().GetTest(2));
break;
case R.id.buttonMiracast:
Log.d("mzhe", "click button set one");
SystemSettingImpl.getInstance().SetTest(1, 1111);
Log.d("mzhe", "test one = " + SystemSettingImpl.getInstance().GetTest(1));
break;
case R.id.buttonMedia:
Log.d("mzhe", "click button set two");
SystemSettingImpl.getInstance().SetTest(2, 2222);
Log.d("mzhe", "test two = " + SystemSettingImpl.getInstance().GetTest(2));
break;
case R.id.buttonStore:
Log.d("mzhe", "click button set menureset");
SystemSettingImpl.getInstance().RestoreTest(true);
Log.d("mzhe", "test one = " + SystemSettingImpl.getInstance().GetTest(1));
Log.d("mzhe", "test two = " + SystemSettingImpl.getInstance().GetTest(2));
break;
case R.id.buttonInputSource:
Log.d("mzhe", "click button set allreset");
SystemSettingImpl.getInstance().RestoreTest(false);
Log.d("mzhe", "test one = " + SystemSettingImpl.getInstance().GetTest(1));
Log.d("mzhe", "test two = " + SystemSettingImpl.getInstance().GetTest(2));
break;
default:
break;
}
}
使用的时候记得关闭selinux,或者加上对应的权限也行。这里简单调试,就直接setenforce 0关闭selinux了
总结
本文是实例分享,做了个简单demo,图方便直接使用了system module。
其实海思有预留客户空间,专门用来客制化hippo接口,有兴趣的话可以去了解CusExImpl结构。可以把所有客制化接口放单独的文件夹统一管理。