538 lines
18 KiB
C++
538 lines
18 KiB
C++
/*----------------------------------------------------------------------------
|
|
* Copyright (c) TJD Technologies Co., Ltd. 2024. All rights reserved.
|
|
*
|
|
* Description: TjdUiWatchFaceCtrl.cpp
|
|
*
|
|
* Author: liuguanwu
|
|
*
|
|
* Create: 2024-10
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
#include "fs_user_common.h"
|
|
#include "sql_setting.h"
|
|
#include "sys_config.h"
|
|
#include "sys_typedef.h"
|
|
#include <dirent.h>
|
|
#include <fstream>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#if ENABLE_MEMORY_CHECK
|
|
#include "gfx_utils/mem_check.h"
|
|
#endif
|
|
#include "DialBinParser.h"
|
|
#include "DialViewGroup.h"
|
|
#include "TjdUiAppMainView.h"
|
|
#include "TjdUiImageIds.h"
|
|
#include "TjdUiWFPageCustom.h"
|
|
#include "TjdUiWFPageFootball.h"
|
|
#include "TjdUiWFPageFootballOne.h"
|
|
#include "TjdUiWatchFaceCtrl.h"
|
|
#include "cJSON.h"
|
|
#include "graphic_service.h"
|
|
#include "power_display_service.h"
|
|
|
|
using namespace OHOS;
|
|
namespace TJD {
|
|
|
|
#define ENABLE_PRINT_INFO 1
|
|
#if ENABLE_PRINT_INFO
|
|
#define static_print_info(...) sys_ui_log_i(__VA_ARGS__) //一般信息打印宏控制
|
|
#define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) //警告信息打印一般常开
|
|
#define static_print_error(...) sys_ui_log_e(__VA_ARGS__) //错误信息打印一般常开
|
|
#define static_print_debug(...) sys_ui_log_d(__VA_ARGS__)
|
|
#else
|
|
#define static_print_info(...)
|
|
#define static_print_warn(...)
|
|
#define static_print_error(...)
|
|
#define static_print_debug(...)
|
|
#endif
|
|
|
|
#define WF_NUMBER_MAX (20)
|
|
//#define TJD_FS_DIR_WF "img_main_wf.bin"
|
|
#define WF_BIN_PATH TJD_FS_DIR_WF
|
|
|
|
struct WFIDCtrl
|
|
{
|
|
uint32_t CurId;
|
|
uint32_t CurNumber;
|
|
uint32_t WFIDList[WF_NUMBER_MAX];
|
|
};
|
|
|
|
static struct WFIDCtrl g_WFInfo = {};
|
|
|
|
struct WFViewMapper
|
|
{
|
|
uint32_t WFId;
|
|
std::function<TjdUiWfBase *(uint32_t id)> func;
|
|
std::string PreviewImgFullPath;
|
|
uint32_t PreviewImgID;
|
|
std::string WFName;
|
|
};
|
|
|
|
/**********************************************************************************************************************
|
|
* PUBLIC FUNCTIONS
|
|
*/
|
|
static TjdUiWfBase *InitNativeDial0(uint32_t id)
|
|
{
|
|
static_print_debug("InitNativeDial0");
|
|
TjdUiWfBase *cardPage = new TjdUiWFPageCustom();
|
|
if (cardPage == nullptr) {
|
|
static_print_error("MainClockView new fail");
|
|
return nullptr;
|
|
}
|
|
return cardPage;
|
|
}
|
|
|
|
// static TjdUiWfBase *InitNativeDial1(uint32_t id)
|
|
// {
|
|
// static_print_debug("InitNativeDial1");
|
|
// TjdUiWfBase *cardPage = new TjdUiWFPageFootball();
|
|
// if (cardPage == nullptr) {
|
|
// static_print_error("MainClockView new fail");
|
|
// return nullptr;
|
|
// }
|
|
// return cardPage;
|
|
// }
|
|
|
|
static TjdUiWfBase *InitNativeDial2(uint32_t id)
|
|
{
|
|
static_print_debug("InitNativeDial2");
|
|
TjdUiWfBase *cardPage = new TjdUiWFPageFootballOne();
|
|
if (cardPage == nullptr) {
|
|
static_print_error("MainClockView new fail");
|
|
return nullptr;
|
|
}
|
|
return cardPage;
|
|
}
|
|
|
|
static const WFViewMapper g_wfViewNativeMapper_[] = {
|
|
{0, &InitNativeDial0, "/user/tjd_res/img_wf_preview.bin", IMG_WF_PREVIEW_DEF_PREVIEW, "视频表盘"},
|
|
//{1, &InitNativeDial1, "/user/tjd_res/img_football.bin", IMG_FOOTBALL_PREVIEW},
|
|
{2, &InitNativeDial2, "/user/tjd_res/img_wf_preview.bin", IMG_WF_PREVIEW_FOOTBALL_PREVIEW, "足球表盘"}};
|
|
|
|
static TjdUiWfBase *InitNativeDial(uint32_t id)
|
|
{
|
|
TjdUiWfBase *cardPage{nullptr};
|
|
|
|
uint32_t count = sizeof(g_wfViewNativeMapper_) / sizeof(g_wfViewNativeMapper_[0]);
|
|
for (uint32_t i = 0; i < count; i++) {
|
|
static_print_debug("InitNativeDial for[%d][%d]]", i, id);
|
|
if (g_wfViewNativeMapper_[i].WFId == id) {
|
|
cardPage = g_wfViewNativeMapper_[i].func(id);
|
|
return cardPage;
|
|
}
|
|
}
|
|
return cardPage;
|
|
}
|
|
|
|
static TjdUiWfBase *InitClondDial(uint32_t id)
|
|
{
|
|
if (TjdUiWfGeTypebyID(id) != WF_FORMAT_CLOUD) {
|
|
return nullptr;
|
|
}
|
|
|
|
std::string fullPath = "";
|
|
TjdUiWfGetFullPathbyID(id, &fullPath);
|
|
FILE *fp = fopen(fullPath.c_str(), "rb");
|
|
if (!fp) {
|
|
static_print_error("InitClondDial fopen error:[%s]", fullPath.c_str());
|
|
return nullptr;
|
|
}
|
|
fclose(fp);
|
|
DialViewGroup *dial = new DialViewGroup();
|
|
TjdUiWfBase *basedial = new TjdUiWfBase(dial);
|
|
dial->SetViewId("wf_main_baseCont_");
|
|
dial->SetDial(fullPath);
|
|
dial->PreLoad();
|
|
dial->OnActive();
|
|
return basedial;
|
|
}
|
|
|
|
UICardPage *TjdUiWfCtrlInit(void)
|
|
{
|
|
uint32_t cur_id = sql_setting_get_watch_face_id();
|
|
static_print_debug("TjdUiWfCtrlInit:cur_id=%d", cur_id);
|
|
TjdUiWfBase *cardPage{nullptr};
|
|
TjdUiWfSetCurID(cur_id);
|
|
|
|
EnumWfFormat type = TjdUiWfGeTypebyID(cur_id);
|
|
if (type == WF_FORMAT_NATIVE) {
|
|
cardPage = InitNativeDial(cur_id);
|
|
} else if (type == WF_FORMAT_CLOUD) {
|
|
cardPage = InitClondDial(cur_id);
|
|
}
|
|
|
|
//使用默认表盘0
|
|
if (cardPage == nullptr) {
|
|
cardPage = InitNativeDial(0);
|
|
TjdUiWfSetCurID(0);
|
|
sql_setting_set_watch_face_id(0);
|
|
}
|
|
TjdUiAppMainView::GetInstance()->GetWfCommon()->LoadWFAfter(cardPage);
|
|
return dynamic_cast<UICardPage *>(cardPage);
|
|
}
|
|
|
|
void TjdUiWfSetCurID(uint32_t id) { g_WFInfo.CurNumber = id; }
|
|
|
|
uint32_t TjdUiWfGetNumberMax(void) { return WF_NUMBER_MAX; }
|
|
|
|
uint32_t TjdUiWfGetCurID(void) { return g_WFInfo.CurNumber; }
|
|
|
|
EnumWfFormat TjdUiWfGeTypebyID(uint32_t id) //表盘格式
|
|
{
|
|
uint32_t count = sizeof(g_wfViewNativeMapper_) / sizeof(g_wfViewNativeMapper_[0]);
|
|
for (uint32_t i = 0; i < count; i++) {
|
|
if (g_wfViewNativeMapper_[i].WFId == id) {
|
|
return WF_FORMAT_NATIVE;
|
|
}
|
|
}
|
|
return WF_FORMAT_CLOUD;
|
|
|
|
if (id > WF_FORMAT_JS_MAX_ID) {
|
|
return WF_FORMAT_CLOUD;
|
|
} else if (id > WF_FORMAT_NATIVE_MAX_ID) {
|
|
return WF_FORMAT_JS;
|
|
} else {
|
|
return WF_FORMAT_NATIVE;
|
|
}
|
|
}
|
|
|
|
void TjdUiWfGetNamebyID(uint32_t id, std::string *StrName) //表盘名称
|
|
{
|
|
StrName->clear();
|
|
StrName->append(std::to_string(id));
|
|
static_print_debug("TjdUiWfGetNamebyID[%s]", StrName->c_str());
|
|
}
|
|
|
|
void TjdUiWfGetFullPathbyID(uint32_t id, std::string *StrPath) //表盘路径,仅云表盘使用
|
|
{
|
|
StrPath->clear();
|
|
if (TjdUiWfGeTypebyID(id) == WF_FORMAT_CLOUD) {
|
|
StrPath->append("/user/tjd_wf/hi_" + std::to_string(id) + ".bwf");
|
|
}
|
|
}
|
|
|
|
void TjdUiWfIDListClear(void)
|
|
{
|
|
for (uint32_t i = 0; i < WF_NUMBER_MAX; i++) {
|
|
g_WFInfo.WFIDList[i] = 0;
|
|
}
|
|
g_WFInfo.CurNumber = 0;
|
|
}
|
|
|
|
void TjdUiWfIDListPush(uint32_t id) { g_WFInfo.WFIDList[g_WFInfo.CurNumber++] = id; }
|
|
|
|
uint32_t *TjdUiWfGetIDList(uint32_t *len)
|
|
{
|
|
uint32_t TempID = 0;
|
|
TjdUiWfIDListClear();
|
|
|
|
//本地表盘
|
|
uint32_t count = sizeof(g_wfViewNativeMapper_) / sizeof(g_wfViewNativeMapper_[0]);
|
|
for (uint32_t i = 0; i < count; i++) {
|
|
TjdUiWfIDListPush(g_wfViewNativeMapper_[i].WFId);
|
|
static_print_debug("FindWfFile number: %d", g_wfViewNativeMapper_[i].WFId);
|
|
}
|
|
|
|
// 云表盘:打开目录
|
|
struct dirent *direntp;
|
|
DIR *dirp = opendir(TJD_FS_DIR_WF);
|
|
// 遍历文件
|
|
if (dirp != nullptr) {
|
|
std::string DirPrePath(TJD_FS_DIR_WF);
|
|
while ((direntp = readdir(dirp)) != nullptr) {
|
|
std::string filename(direntp->d_name);
|
|
if (filename.find(".bwf") != std::string::npos && filename.find("hi_") != std::string::npos) {
|
|
std::string number;
|
|
std::size_t pos1 = filename.find_last_of('_');
|
|
if (pos1 != std::string::npos) {
|
|
// 查找 .bin 的位置
|
|
std::size_t pos2 = filename.find(".bwf", pos1);
|
|
if (pos2 != std::string::npos) {
|
|
// 提取下划线和 .bin 之间的子字符串
|
|
number = filename.substr(pos1 + 1, pos2 - pos1 - 1);
|
|
static_print_debug("FindWfFile number: %s", number.c_str());
|
|
}
|
|
}
|
|
TempID = std::stoi(number);
|
|
if (TempID > WF_FORMAT_JS_MAX_ID) {
|
|
TjdUiWfIDListPush(TempID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// 关闭目录
|
|
closedir(dirp);
|
|
*len = g_WFInfo.CurNumber;
|
|
return &g_WFInfo.WFIDList[0];
|
|
}
|
|
|
|
bool TjdUiGetWfSelectInfoByConfig(uint32_t id, WfSelectInfo *info)
|
|
{
|
|
//本地表盘json 分析
|
|
bool json_flag = false;
|
|
std::string fullPath = "/user/tjd_wf/wf_config_0.json";
|
|
std::ifstream file(fullPath);
|
|
if (file.is_open()) {
|
|
// 使用 stringstream 读取文件内容
|
|
std::stringstream buffer;
|
|
buffer << file.rdbuf();
|
|
// 将文件内容存储到字符串中
|
|
std::string fileContent = buffer.str();
|
|
static_print_debug("TjdUiGetWfSelectInfoDefault::%s file content:%s", __func__, fileContent.c_str());
|
|
cJSON *cjson_root = cJSON_Parse(fileContent.c_str());
|
|
if (cjson_root == NULL) {
|
|
static_print_error("parse fail.");
|
|
file.close();
|
|
return json_flag;
|
|
}
|
|
cJSON *cjsonType = cJSON_GetObjectItem(cjson_root, "wf_type");
|
|
cJSON *cjsonWfPath = cJSON_GetObjectItem(cjson_root, "wf_preview");
|
|
static_print_debug("TjdUiGetWfSelectInfoDefault:: wf_type:%d, wf_preview:%s", cjsonType->valueint,
|
|
cJSON_GetStringValue(cjsonWfPath));
|
|
if (strlen(cJSON_GetStringValue(cjsonWfPath))) {
|
|
info->wfId = id;
|
|
switch (cjsonType->valueint) {
|
|
case 2:
|
|
info->name = "视频表盘";
|
|
break;
|
|
default:
|
|
info->name = "自定义表盘";
|
|
break;
|
|
}
|
|
info->PreviewImgFileOffset = -1; //单独文件标识
|
|
info->PreviewImgFullPath.clear();
|
|
info->PreviewImgFullPath.append(std::string(cJSON_GetStringValue(cjsonWfPath)));
|
|
info->PreviewImgId = 0;
|
|
json_flag = true;
|
|
#if 0
|
|
std::size_t pos = info.path.find_last_of('/');
|
|
std::string filename;
|
|
if (pos != std::string::npos) {
|
|
info.name = info.path.substr(pos + 1);
|
|
// std::size_t pos = info.name.find(".bin");
|
|
// if (pos != std::string::npos) {
|
|
// info.name = info.name.substr(0, pos);
|
|
// }
|
|
} else {
|
|
info.name = "wf_0.bwf";
|
|
}
|
|
#endif
|
|
// printf("TjdUiGetWfSelectInfoDefault::FindWfFile: %s", info->name.c_str());
|
|
} else {
|
|
static_print_debug("TjdUiGetWfSelectInfoDefault:: fail:strlen:%d",
|
|
strlen(cJSON_GetStringValue(cjsonWfPath)));
|
|
}
|
|
cJSON_Delete(cjson_root);
|
|
}
|
|
// 关闭文件
|
|
file.close();
|
|
return json_flag;
|
|
}
|
|
|
|
bool TjdUiWfGetSelectInfobyID(uint32_t id, WfSelectInfo *info)
|
|
{
|
|
static_print_debug("TjdUiGetWfSelectInfo: %d[%p]", id, info);
|
|
if (id == 0) {
|
|
if (TjdUiGetWfSelectInfoByConfig(id, info)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
EnumWfFormat wfType = TjdUiWfGeTypebyID(id);
|
|
info->wfId = id;
|
|
|
|
if (wfType == WF_FORMAT_CLOUD) {
|
|
TjdUiWfGetFullPathbyID(id, &info->PreviewImgFullPath);
|
|
FILE *fp = fopen(info->PreviewImgFullPath.c_str(), "rb");
|
|
DialPreviewInfo preInfo{};
|
|
bool ret = DialBinParserManager::GetInstance()->GetDialPreviewInfo(fp, &preInfo);
|
|
fclose(fp);
|
|
info->name = preInfo.dialName;
|
|
info->PreviewImgFileOffset = preInfo.offset;
|
|
info->PreviewImgId = preInfo.imgId;
|
|
return true;
|
|
}
|
|
|
|
if (wfType == WF_FORMAT_NATIVE) {
|
|
uint32_t count = sizeof(g_wfViewNativeMapper_) / sizeof(g_wfViewNativeMapper_[0]);
|
|
for (uint32_t i = 0; i <= count; i++) {
|
|
if (g_wfViewNativeMapper_[i].WFId == id) {
|
|
info->PreviewImgFileOffset = 0;
|
|
info->PreviewImgFullPath = g_wfViewNativeMapper_[i].PreviewImgFullPath;
|
|
info->PreviewImgId = g_wfViewNativeMapper_[i].PreviewImgID;
|
|
info->name = g_wfViewNativeMapper_[i].WFName;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool TjdUiWfGeUninstallbyID(uint32_t id)
|
|
{
|
|
uint32_t count = sizeof(g_wfViewNativeMapper_) / sizeof(g_wfViewNativeMapper_[0]);
|
|
for (uint32_t i = 0; i < count; i++) {
|
|
if (g_wfViewNativeMapper_[i].WFId == id) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#define LOCAL_WF_ID_1 50117
|
|
bool TjdUiWfIsLocalID(uint32_t id)
|
|
{
|
|
const int offset = id - LOCAL_WF_ID_1;
|
|
if (offset < 0 || offset > 8) {
|
|
return 0;
|
|
}
|
|
const unsigned int mask = 0x1F3;
|
|
return (mask >> offset) & 1;
|
|
}
|
|
|
|
void TjdUIWfRename(std::string fullPath)
|
|
{
|
|
static_print_debug("TjdUIWfRename: %s", fullPath.c_str());
|
|
size_t lastDotPos = fullPath.find_last_of('.');
|
|
std::string newPath = fullPath.substr(0, lastDotPos) + ".bak";
|
|
if (access(newPath.c_str(), F_OK) == 0) {
|
|
tjd_fs_api_unlink(fullPath.c_str());
|
|
} else {
|
|
rename(fullPath.c_str(), newPath.c_str());
|
|
}
|
|
}
|
|
|
|
void TjdUiWfRecovery(void)
|
|
{
|
|
static_print_debug("TjdUiWfRecovery:");
|
|
// 云表盘:打开目录
|
|
uint32_t TempID = 0;
|
|
struct dirent *direntp;
|
|
DIR *dirp = opendir(TJD_FS_DIR_WF);
|
|
// 遍历文件
|
|
if (dirp != nullptr) {
|
|
std::string DirPrePath(TJD_FS_DIR_WF);
|
|
while ((direntp = readdir(dirp)) != nullptr) {
|
|
std::string filename(direntp->d_name);
|
|
if (filename.find("hi_") != std::string::npos) {
|
|
if (filename.find(".bak") != std::string::npos) {
|
|
std::size_t pos = filename.find_last_of('.');
|
|
if (pos != std::string::npos) {
|
|
std::string newName = filename.substr(0, pos) + ".bwf";
|
|
std::string newPath = DirPrePath + "/" + newName;
|
|
std::string oldPath = DirPrePath + "/" + filename;
|
|
if (access(newPath.c_str(), F_OK) == 0) { //先删除,再使用备份文件
|
|
tjd_fs_api_unlink(newPath.c_str());
|
|
}
|
|
rename(oldPath.c_str(), newPath.c_str());
|
|
}
|
|
} else if (filename.find(".bwf") != std::string::npos) {
|
|
std::string number;
|
|
std::size_t pos1 = filename.find_last_of('_');
|
|
if (pos1 != std::string::npos) {
|
|
std::size_t pos2 = filename.find(".bwf", pos1);
|
|
if (pos2 != std::string::npos) {
|
|
// 提取下划线和 .bwf 之间的子字符串
|
|
number = filename.substr(pos1 + 1, pos2 - pos1 - 1);
|
|
static_print_debug("FindWfFile number: %s", number.c_str());
|
|
}
|
|
}
|
|
TempID = std::stoi(number);
|
|
std::string Path = DirPrePath + "/" + filename;
|
|
if (TjdUiWfIsLocalID(TempID)) {
|
|
std::size_t pos = filename.find_last_of('.');
|
|
if (pos != std::string::npos) {
|
|
std::string bakName = filename.substr(0, pos) + ".bak";
|
|
std::string bakpath = DirPrePath + "/" + bakName;
|
|
if (access(bakpath.c_str(), F_OK) == 0) {
|
|
tjd_fs_api_unlink(Path.c_str());
|
|
}
|
|
}
|
|
} else {
|
|
tjd_fs_api_unlink(Path.c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// 关闭目录
|
|
closedir(dirp);
|
|
}
|
|
|
|
bool TjdUiWfDeletebyID(uint32_t id)
|
|
{
|
|
std::string fullPath{nullptr};
|
|
TjdUiWfGetFullPathbyID(id, &fullPath);
|
|
if (fullPath.size()) {
|
|
if (TjdUiWfIsLocalID(id)) {
|
|
TjdUIWfRename(fullPath);
|
|
} else {
|
|
tjd_fs_api_unlink(fullPath.c_str()); // int unlink(FAR const char *pathname)
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool TjdUiWfInstallBeforNotify(uint32_t id) { return true; }
|
|
|
|
static void TjdUiWfInstallAfterNotifyRun(void)
|
|
{
|
|
static_print_debug("TjdUiWfInstallAfterNotifyRun: ");
|
|
if (power_display_svr_get_api()->get_screen_state() != SCREEN_ON) {
|
|
power_display_svr_get_api()->turn_on_screen();
|
|
}
|
|
power_display_svr_get_api()->set_auto_timeout_function(true);
|
|
uint16_t current_slice_id = OHOS::NativeAbility::GetInstance().GetCurSliceId();
|
|
if (current_slice_id != TJD_APP_VIEW_MAIN) { // 主表盘
|
|
OHOS::NativeAbility::GetInstance().ChangeSlice(TJD_APP_VIEW_MAIN);
|
|
} else {
|
|
// 当前页面为主表盘的其他页面时,切换回主表盘页面
|
|
// TJD::TjdUiAppMainView::GetInstance()->ResetView();
|
|
// OHOS::NativeAbility::GetInstance().StopAbility();
|
|
// OHOS::NativeAbility::GetInstance().StartAbility();
|
|
OHOS::NativeAbility::GetInstance().ChangeSlice(TJD_APP_VIEW_OPEN_LOGO);
|
|
OHOS::NativeAbility::GetInstance().ChangeSlice(TJD_APP_VIEW_MAIN);
|
|
}
|
|
}
|
|
|
|
bool TjdUiWfInstallAfterNotify(uint32_t id)
|
|
{
|
|
static_print_debug("TjdUiWfInstallAfterNotify: %d", id);
|
|
sql_setting_set_watch_face_id(id);
|
|
GraphicService::GetInstance()->PostGraphicEvent([] { TjdUiWfInstallAfterNotifyRun(); });
|
|
return true;
|
|
}
|
|
|
|
bool TjdUiWfUninstallBeforNotify(uint32_t id) { return true; }
|
|
|
|
static void TjdUiWfUninstallAfterNotifyRun(void)
|
|
{
|
|
static_print_debug("TjdUiWfUninstallAfterNotifyRun:");
|
|
uint16_t current_slice_id = OHOS::NativeAbility::GetInstance().GetCurSliceId();
|
|
if (current_slice_id == TJD_APP_VIEW_MAIN) { // 主表盘
|
|
if (power_display_svr_get_api()->get_screen_state() != SCREEN_ON) {
|
|
power_display_svr_get_api()->turn_on_screen();
|
|
}
|
|
power_display_svr_get_api()->set_auto_timeout_function(true);
|
|
OHOS::NativeAbility::GetInstance().ChangeSlice(TJD_APP_VIEW_OPEN_LOGO);
|
|
OHOS::NativeAbility::GetInstance().ChangeSlice(TJD_APP_VIEW_MAIN);
|
|
}
|
|
}
|
|
|
|
bool TjdUiWfUninstallAfterNotify(uint32_t id)
|
|
{
|
|
static_print_debug("TjdUiWfUninstallAfterNotify: %d", id);
|
|
if (id == 0) {
|
|
return true;
|
|
}
|
|
if (id == sql_setting_get_watch_face_id()) {
|
|
sql_setting_set_watch_face_id(0);
|
|
GraphicService::GetInstance()->PostGraphicEvent([] { TjdUiWfUninstallAfterNotifyRun(); });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace TJD
|