1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "distributed_extension_service.h"
17
18 #include "ans_log_wrapper.h"
19 #include "event_report.h"
20 #include "notification_analytics_util.h"
21 #include "distributed_device_data_service.h"
22
23 #include <utility>
24
25 namespace OHOS {
26 namespace Notification {
27
28 using namespace DistributedHardware;
29
30 using DeviceCallback = std::function<bool(std::string, int32_t, bool)>;
31 typedef int32_t (*INIT_LOCAL_DEVICE)(const std::string &deviceId, uint16_t deviceType,
32 DistributedDeviceConfig config, DistributedHaCallbacks callbacks);
33 typedef void (*RELEASE_LOCAL_DEVICE)();
34 typedef void (*ADD_DEVICE)(const std::string &deviceId, const std::string &udId,
35 uint16_t deviceType, const std::string &networkId);
36 typedef void (*RELEASE_DEVICE)(const std::string &deviceId, uint16_t deviceType);
37 typedef void (*REFRESH_DEVICE)(const std::string &deviceId, uint16_t deviceType,
38 const std::string &networkId);
39 typedef void (*CHANGE_STATUS)(const DeviceStatueChangeInfo& changeInfo);
40 typedef void (*INIT_HA_CALLBACK)(
41 std::function<void(int32_t, int32_t, uint32_t, std::string)> callback);
42 typedef void (*INIT_SENDREPORT_CALLBACK)(
43 std::function<void(int32_t, int32_t, std::string)> callback);
44
45 namespace {
46 constexpr int32_t DEFAULT_TITLE_LENGTH = 200;
47 constexpr int32_t DEFAULT_CONTENT_LENGTH = 400;
48 constexpr uint64_t IDEL_TASK_DELAY = 30 * 1000 * 1000;
49 constexpr char const APP_ID[] = "com.ohos.notification_service.3203";
50 constexpr const char* CFG_KEY_DISTRIBUTED = "distribuedConfig";
51 constexpr const char* CFG_KEY_LOCAL_TYPE = "localType";
52 constexpr const char* CFG_KEY_SUPPORT_DEVICES = "supportPeerDevice";
53 constexpr const char* CFG_KEY_TITLE_LENGTH = "maxTitleLength";
54 constexpr const char* CFG_KEY_CONTENT_LENGTH = "maxContentLength";
55 constexpr const char* CFG_KEY_REPLY_TIMEOUT = "operationReplyTimeout";
56 constexpr const int32_t PUBLISH_ERROR_EVENT_CODE = 0;
57 constexpr const int32_t DELETE_ERROR_EVENT_CODE = 5;
58 constexpr const int32_t MODIFY_ERROR_EVENT_CODE = 6;
59 constexpr const int32_t ANS_CUSTOMIZE_CODE = 7;
60
61 constexpr int64_t DURATION_ONE_SECOND = 1000; // 1s, millisecond
62 }
63
TransDeviceTypeToName(uint16_t deviceType_)64 std::string DistributedExtensionService::TransDeviceTypeToName(uint16_t deviceType_)
65 {
66 switch (deviceType_) {
67 case DmDeviceType::DEVICE_TYPE_WATCH: {
68 return "Watch";
69 }
70 case DmDeviceType::DEVICE_TYPE_PAD: {
71 return "Tablet";
72 }
73 case DmDeviceType::DEVICE_TYPE_PHONE: {
74 return "Phone";
75 }
76 case DmDeviceType::DEVICE_TYPE_2IN1: {
77 return "Pc";
78 }
79 case DmDeviceType::DEVICE_TYPE_PC: {
80 return "Pc";
81 }
82 default:
83 return "";
84 }
85 }
86
DeviceTypeToTypeString(uint16_t deviceType)87 std::string DistributedExtensionService::DeviceTypeToTypeString(uint16_t deviceType)
88 {
89 switch (deviceType) {
90 case DistributedHardware::DmDeviceType::DEVICE_TYPE_PAD: {
91 return "tablet";
92 }
93 case DistributedHardware::DmDeviceType::DEVICE_TYPE_PC: {
94 return "2in1";
95 }
96 case DistributedHardware::DmDeviceType::DEVICE_TYPE_2IN1: {
97 return "2in1";
98 }
99 default:
100 return "";
101 }
102 }
103
GetInstance()104 DistributedExtensionService& DistributedExtensionService::GetInstance()
105 {
106 static DistributedExtensionService distributedExtensionService;
107 return distributedExtensionService;
108 }
109
DistributedExtensionService()110 DistributedExtensionService::DistributedExtensionService()
111 {
112 if (!initConfig()) {
113 return;
114 }
115 distributedQueue_ = std::make_shared<ffrt::queue>("ans_extension");
116 if (distributedQueue_ == nullptr) {
117 ANS_LOGE("ffrt create failed!");
118 return;
119 }
120 }
121
~DistributedExtensionService()122 DistributedExtensionService::~DistributedExtensionService()
123 {
124 if (distributedQueue_ == nullptr) {
125 ANS_LOGI("Dans already release.");
126 return;
127 }
128 std::function<void()> task = std::bind([&]() {
129 ReleaseLocalDevice();
130 dansHandler_.reset();
131 dansRunning_.store(false);
132 });
133 ANS_LOGI("Dans release.");
134 ffrt::task_handle handler = distributedQueue_->submit_h(task);
135 distributedQueue_->wait(handler);
136 }
137
initConfig()138 bool DistributedExtensionService::initConfig()
139 {
140 nlohmann::json root;
141 std::string jsonPoint = "/";
142 jsonPoint.append(NotificationConfigParse::CFG_KEY_NOTIFICATION_SERVICE);
143 jsonPoint.append("/");
144 jsonPoint.append(CFG_KEY_DISTRIBUTED);
145 if (!NotificationConfigParse::GetInstance()->GetConfigJson(jsonPoint, root)) {
146 return false;
147 }
148
149 if (root.find(NotificationConfigParse::CFG_KEY_NOTIFICATION_SERVICE) == root.end()) {
150 ANS_LOGE("Dans initConfig failed as can not find notificationService.");
151 return false;
152 }
153
154 nlohmann::json configJson = root[NotificationConfigParse::CFG_KEY_NOTIFICATION_SERVICE][CFG_KEY_DISTRIBUTED];
155 if (configJson.is_null() || configJson.empty()) {
156 ANS_LOGE("Dans initConfig failed as invalid json.");
157 return false;
158 }
159
160 SetLocalType(configJson);
161 if (!SetSupportPeerDevice(configJson)) {
162 return false;
163 }
164 SetMaxTitleLength(configJson);
165 SetMaxContentLength(configJson);
166 SetOperationReplyTimeout(configJson);
167
168 deviceConfig_.collaborativeDeleteTypes = NotificationConfigParse::GetInstance()->GetCollaborativeDeleteType();
169 deviceConfig_.startAbilityTimeout = NotificationConfigParse::GetInstance()->GetStartAbilityTimeout();
170 std::map<std::string, std::map<std::string, std::unordered_set<std::string>>> map;
171 auto res = NotificationConfigParse::GetInstance()->GetCollaborativeDeleteTypeByDevice(map);
172 if (res && !map.empty()) {
173 deviceConfig_.collaborativeDeleteTypesByDevice = map;
174 }
175 return true;
176 }
177
InitDans()178 int32_t DistributedExtensionService::InitDans()
179 {
180 if (dansRunning_.load() && dansHandler_ != nullptr && dansHandler_->IsValid()) {
181 return 0;
182 }
183 dansHandler_ = std::make_shared<NotificationLoadUtils>("libdans.z.so");
184 if (dansHandler_ == nullptr) {
185 ANS_LOGW("Dans handler init failed.");
186 return -1;
187 }
188
189 INIT_LOCAL_DEVICE handler = (INIT_LOCAL_DEVICE)dansHandler_->GetProxyFunc("InitLocalDevice");
190 if (handler == nullptr) {
191 ANS_LOGW("Dans init failed.");
192 return -1;
193 }
194
195 DmDeviceInfo deviceInfo;
196 int32_t result = DeviceManager::GetInstance().GetLocalDeviceInfo(APP_ID, deviceInfo);
197 if (result != 0) {
198 ANS_LOGW("Dans get local device failed.");
199 return -1;
200 }
201
202 DistributedHaCallbacks distributedCallbacks = {
203 std::bind(&DistributedExtensionService::SendReportCallback, this, std::placeholders::_1,
204 std::placeholders::_2, std::placeholders::_3),
205 std::bind(&DistributedExtensionService::HADotCallback, this, std::placeholders::_1,
206 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
207 std::bind(&DistributedExtensionService::HaOperationCallback, this, std::placeholders::_1,
208 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
209 };
210
211 ANS_LOGI("Dans get local device %{public}s, %{public}d, %{public}d, %{public}d.",
212 StringAnonymous(deviceInfo.deviceId).c_str(), deviceInfo.deviceTypeId,
213 deviceConfig_.maxTitleLength, deviceConfig_.maxContentLength);
214 if (handler(deviceInfo.deviceId, deviceInfo.deviceTypeId, deviceConfig_, distributedCallbacks) != 0) {
215 dansRunning_.store(false);
216 return -1;
217 }
218
219 dansRunning_.store(true);
220 return 0;
221 }
222
ReleaseLocalDevice()223 int32_t DistributedExtensionService::ReleaseLocalDevice()
224 {
225 if (!dansRunning_.load() || dansHandler_ == nullptr || !dansHandler_->IsValid()) {
226 return 0;
227 }
228
229 RELEASE_LOCAL_DEVICE handler = (RELEASE_LOCAL_DEVICE)dansHandler_->GetProxyFunc("ReleaseLocalDevice");
230 if (handler == nullptr) {
231 ANS_LOGW("Dans release failed, handler is null.");
232 return -1;
233 }
234 handler();
235 ANS_LOGI("Dans release successfully.");
236 return 0;
237 }
238
TransDeviceIdToUdid(const std::string & networkId,std::string & udid)239 int32_t DistributedExtensionService::TransDeviceIdToUdid(const std::string& networkId, std::string& udid)
240 {
241 int32_t ret = DeviceManager::GetInstance().GetUdidByNetworkId(APP_ID, networkId, udid);
242 if (ret != 0) {
243 ANS_LOGE("On line device failed, %{public}s ret:%{public}d",
244 StringAnonymous(networkId).c_str(), ret);
245 return ret;
246 }
247 ANS_LOGI("OnDeviceOnline id change %{public}s %{public}s", StringAnonymous(networkId).c_str(),
248 StringAnonymous(udid).c_str());
249 return ERR_OK;
250 }
251
OnDeviceOnline(const DmDeviceInfo & deviceInfo)252 void DistributedExtensionService::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
253 {
254 std::string name = TransDeviceTypeToName(deviceInfo.deviceTypeId);
255 if (deviceConfig_.supportPeerDevice.find(name) == deviceConfig_.supportPeerDevice.end()) {
256 ANS_LOGE("The current device type not support %{public}d.", deviceInfo.deviceTypeId);
257 return;
258 }
259 if (distributedQueue_ == nullptr) {
260 return;
261 }
262 std::function<void()> onlineTask = std::bind([&, deviceInfo]() {
263 if (InitDans() != 0) {
264 ANS_LOGE("OnDeviceOnline init dans failed.");
265 return;
266 };
267 std::string udid;
268 if (TransDeviceIdToUdid(deviceInfo.networkId, udid) != ERR_OK) {
269 return;
270 }
271 ADD_DEVICE handler = (ADD_DEVICE)dansHandler_->GetProxyFunc("AddDevice");
272 if (handler == nullptr) {
273 ANS_LOGE("Dans handler is null ptr.");
274 return;
275 }
276 std::lock_guard<ffrt::mutex> lock(mapLock_);
277 DistributedDeviceDataService::GetInstance().ResetTargetDevice(
278 DeviceTypeToTypeString(deviceInfo.deviceTypeId), deviceInfo.deviceId);
279 handler(deviceInfo.deviceId, udid, deviceInfo.deviceTypeId, deviceInfo.networkId);
280 std::string reason = "deviceType: " + std::to_string(deviceInfo.deviceTypeId) +
281 " ; deviceId: " + StringAnonymous(deviceInfo.deviceId) + " ; networkId: " +
282 StringAnonymous(deviceInfo.networkId);
283 HADotCallback(PUBLISH_ERROR_EVENT_CODE, 0, EventSceneId::SCENE_1, reason);
284 DistributedDeviceInfo device = DistributedDeviceInfo(deviceInfo.deviceId, deviceInfo.deviceName,
285 deviceInfo.networkId, deviceInfo.deviceTypeId);
286 deviceMap_.insert(std::make_pair(deviceInfo.deviceId, device));
287 });
288 distributedQueue_->submit(onlineTask);
289 }
290
HaOperationCallback(const std::string & deviceType,int32_t sceneType,int32_t slotType,std::string reason)291 void DistributedExtensionService::HaOperationCallback(const std::string& deviceType, int32_t sceneType,
292 int32_t slotType, std::string reason)
293 {
294 bool isLiveView = (slotType == NotificationConstant::SlotType::LIVE_VIEW);
295 ANS_LOGI("HaOperationCallback %{public}s %{public}d %{public}d.", deviceType.c_str(), sceneType, slotType);
296 HaOperationMessage operation = HaOperationMessage(isLiveView);
297 switch (sceneType) {
298 case HaOperationType::COLLABORATE_DELETE: {
299 operation.SyncDelete(deviceType, reason);
300 break;
301 }
302 case HaOperationType::COLLABORATE_REPLY: {
303 operation.SyncReply(deviceType);
304 break;
305 }
306 case HaOperationType::COLLABORATE_JUMP: {
307 operation.SyncClick(deviceType);
308 break;
309 }
310 default:
311 return;
312 }
313 NotificationAnalyticsUtil::ReportOperationsDotEvent(operation);
314 }
315
HADotCallback(int32_t code,int32_t ErrCode,uint32_t branchId,std::string reason)316 void DistributedExtensionService::HADotCallback(int32_t code, int32_t ErrCode, uint32_t branchId, std::string reason)
317 {
318 ANS_LOGI("Dans ha callback %{public}d, %{public}d, %{public}s.", code, ErrCode, reason.c_str());
319 if (code == PUBLISH_ERROR_EVENT_CODE) {
320 if (reason.find("deviceType") != std::string::npos ||
321 reason.find("ShutdownReason") != std::string::npos) {
322 HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_21, branchId).Message(reason);
323 NotificationAnalyticsUtil::ReportPublishFailedEvent(message);
324 } else {
325 HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_20, branchId)
326 .ErrorCode(ErrCode)
327 .Message(reason);
328 NotificationAnalyticsUtil::ReportPublishFailedEvent(message);
329 }
330 } else if (code == DELETE_ERROR_EVENT_CODE) {
331 HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_20, branchId)
332 .DeleteReason(NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE)
333 .ErrorCode(ErrCode)
334 .Message(reason);
335 NotificationAnalyticsUtil::ReportDeleteFailedEvent(message);
336 } else if (code == MODIFY_ERROR_EVENT_CODE) {
337 HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_20, branchId)
338 .ErrorCode(ErrCode)
339 .Message(reason);
340 NotificationAnalyticsUtil::ReportSkipFailedEvent(message);
341 }
342 }
343
SendReportCallback(int32_t messageType,int32_t errCode,std::string reason)344 void DistributedExtensionService::SendReportCallback(
345 int32_t messageType, int32_t errCode, std::string reason)
346 {
347 EventInfo eventInfo;
348 eventInfo.messageType = messageType;
349 eventInfo.errCode = errCode;
350 eventInfo.reason = reason;
351 EventReport::SendHiSysEvent(EVENT_NOTIFICATION_ERROR, eventInfo);
352 }
353
OnDeviceOffline(const DmDeviceInfo & deviceInfo)354 void DistributedExtensionService::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
355 {
356 if (distributedQueue_ == nullptr) {
357 return;
358 }
359 std::function<void()> offlineTask = std::bind([&, deviceInfo]() {
360 std::lock_guard<ffrt::mutex> lock(mapLock_);
361 if (deviceMap_.count(deviceInfo.deviceId) == 0) {
362 ANS_LOGE("Not target device %{public}s", StringAnonymous(deviceInfo.deviceId).c_str());
363 return;
364 }
365 if (!dansRunning_.load() || dansHandler_ == nullptr || !dansHandler_->IsValid()) {
366 ANS_LOGE("Dans state not normal %{public}d", dansRunning_.load());
367 return;
368 }
369 RELEASE_DEVICE handler = (RELEASE_DEVICE)dansHandler_->GetProxyFunc("ReleaseDevice");
370 if (handler == nullptr) {
371 ANS_LOGE("Dans handler is null ptr.");
372 return;
373 }
374 handler(deviceInfo.deviceId, deviceInfo.deviceTypeId);
375 std::string reason = "deviceType: " + std::to_string(deviceInfo.deviceTypeId) +
376 " ; deviceId: " + StringAnonymous(deviceInfo.deviceId);
377 HADotCallback(PUBLISH_ERROR_EVENT_CODE, 0, EventSceneId::SCENE_2, reason);
378 deviceMap_.erase(deviceInfo.deviceId);
379 });
380 distributedQueue_->submit(offlineTask);
381 }
382
OnDeviceChanged(const DmDeviceInfo & deviceInfo)383 void DistributedExtensionService::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
384 {
385 if (distributedQueue_ == nullptr) {
386 return;
387 }
388 std::function<void()> changeTask = std::bind([&, deviceInfo]() {
389 std::lock_guard<ffrt::mutex> lock(mapLock_);
390 if (deviceMap_.count(deviceInfo.deviceId) == 0) {
391 ANS_LOGE("Not target device %{public}s", StringAnonymous(deviceInfo.deviceId).c_str());
392 return;
393 }
394 if (!dansRunning_.load() || dansHandler_ == nullptr || !dansHandler_->IsValid()) {
395 ANS_LOGE("Dans state not normal %{public}d", dansRunning_.load());
396 return;
397 }
398 REFRESH_DEVICE handler = (REFRESH_DEVICE)dansHandler_->GetProxyFunc("RefreshDevice");
399 if (handler == nullptr) {
400 ANS_LOGE("Dans handler is null ptr.");
401 return;
402 }
403 handler(deviceInfo.deviceId, deviceInfo.deviceTypeId, deviceInfo.networkId);
404 std::string reason = "deviceType: " + std::to_string(deviceInfo.deviceTypeId) +
405 " deviceId: " + StringAnonymous(deviceInfo.deviceId) + " networkId: " +
406 StringAnonymous(deviceInfo.networkId);
407 HADotCallback(PUBLISH_ERROR_EVENT_CODE, 0, EventSceneId::SCENE_3, reason);
408 ANS_LOGI("Dans refresh %{public}s %{public}s.", StringAnonymous(deviceInfo.deviceId).c_str(),
409 StringAnonymous(deviceInfo.networkId).c_str());
410 });
411 distributedQueue_->submit(changeTask);
412 }
413
OnAllConnectOnline()414 void DistributedExtensionService::OnAllConnectOnline()
415 {
416 DeviceStatueChangeInfo changeInfo;
417 changeInfo.enableChange = true;
418 changeInfo.changeType = DeviceStatueChangeType::ALL_CONNECT_STATUS_CHANGE;
419 DeviceStatusChange(changeInfo);
420 }
421
DeviceStatusChange(const DeviceStatueChangeInfo & changeInfo)422 void DistributedExtensionService::DeviceStatusChange(const DeviceStatueChangeInfo& changeInfo)
423 {
424 if (distributedQueue_ == nullptr) {
425 return;
426 }
427 std::function<void()> changeTask = std::bind([&, changeInfo]() {
428 if (!dansRunning_.load() || dansHandler_ == nullptr || !dansHandler_->IsValid()) {
429 ANS_LOGE("Dans state not normal %{public}d", dansRunning_.load());
430 return;
431 }
432 CHANGE_STATUS handler = (CHANGE_STATUS)dansHandler_->GetProxyFunc("DeviceStatusChange");
433 if (handler == nullptr) {
434 ANS_LOGE("Dans handler is null ptr.");
435 return;
436 }
437 handler(changeInfo);
438 ANS_LOGI("Dans statuc change %{public}s %{public}d %{public}d %{public}d.",
439 StringAnonymous(changeInfo.deviceId).c_str(), changeInfo.changeType, changeInfo.enableChange,
440 changeInfo.liveViewChange);
441 });
442 distributedQueue_->submit(changeTask);
443 }
444
GetOperationReplyTimeout()445 int32_t DistributedExtensionService::GetOperationReplyTimeout()
446 {
447 return deviceConfig_.operationReplyTimeout * DURATION_ONE_SECOND;
448 }
449
SetOperationReplyTimeout(nlohmann::json & configJson)450 void DistributedExtensionService::SetOperationReplyTimeout(nlohmann::json &configJson)
451 {
452 nlohmann::json contentJson = configJson[CFG_KEY_REPLY_TIMEOUT];
453 if (contentJson.is_null() || contentJson.empty() || !contentJson.is_number_integer()) {
454 deviceConfig_.operationReplyTimeout = DEFAULT_REPLY_TIMEOUT;
455 } else {
456 deviceConfig_.operationReplyTimeout = contentJson.get<int32_t>();
457 ANS_LOGI("Dans initConfig reply timeout %{public}d.", deviceConfig_.operationReplyTimeout);
458 }
459 }
460
SetMaxContentLength(nlohmann::json & configJson)461 void DistributedExtensionService::SetMaxContentLength(nlohmann::json &configJson)
462 {
463 nlohmann::json contentJson = configJson[CFG_KEY_CONTENT_LENGTH];
464 if (contentJson.is_null() || contentJson.empty() || !contentJson.is_number_integer()) {
465 deviceConfig_.maxContentLength = DEFAULT_CONTENT_LENGTH;
466 } else {
467 deviceConfig_.maxContentLength = contentJson.get<int32_t>();
468 ANS_LOGI("Dans initConfig content length %{public}d.", deviceConfig_.maxContentLength);
469 }
470 }
471
SetLocalType(nlohmann::json & configJson)472 bool DistributedExtensionService::SetLocalType(nlohmann::json &configJson)
473 {
474 nlohmann::json localTypeJson = configJson[CFG_KEY_LOCAL_TYPE];
475 if (localTypeJson.is_null() || localTypeJson.empty()) {
476 ANS_LOGE("Dans initConfig local type as invalid json.");
477 return false;
478 }
479
480 if (!localTypeJson.is_string()) {
481 ANS_LOGE("Dans initConfig local type not string");
482 return false;
483 }
484
485 deviceConfig_.localType = localTypeJson.get<std::string>();
486 ANS_LOGI("Dans initConfig local type %{public}s.", deviceConfig_.localType.c_str());
487 return true;
488 }
489
SetSupportPeerDevice(nlohmann::json & configJson)490 bool DistributedExtensionService::SetSupportPeerDevice(nlohmann::json &configJson)
491 {
492 nlohmann::json supportJson = configJson[CFG_KEY_SUPPORT_DEVICES];
493 if (supportJson.is_null() || supportJson.empty() || !supportJson.is_array()) {
494 ANS_LOGE("Dans initConfig support type as invalid json.");
495 return false;
496 }
497
498 for (auto &deviceJson : supportJson) {
499 if (deviceJson.is_string()) {
500 deviceConfig_.supportPeerDevice.insert(deviceJson.get<std::string>());
501 ANS_LOGI("Dans initConfig support type %{public}s.", deviceJson.get<std::string>().c_str());
502 }
503 }
504 return true;
505 }
506
SetMaxTitleLength(nlohmann::json & configJson)507 bool DistributedExtensionService::SetMaxTitleLength(nlohmann::json &configJson)
508 {
509 nlohmann::json titleJson = configJson[CFG_KEY_TITLE_LENGTH];
510 if (titleJson.is_null() || titleJson.empty() || !titleJson.is_number_integer()) {
511 deviceConfig_.maxTitleLength = DEFAULT_TITLE_LENGTH;
512 } else {
513 deviceConfig_.maxTitleLength = titleJson.get<int32_t>();
514 ANS_LOGI("Dans initConfig title length %{public}d.", deviceConfig_.maxTitleLength);
515 }
516 return true;
517 }
518 }
519 }
520