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 #define MLOG_TAG "ringtone_Extension"
16
17 #include "ringtone_datashare_extension.h"
18
19 #include "app_mgr_client.h"
20 #include "datashare_ext_ability_context.h"
21 #include "dfx_manager.h"
22 #include "dfx_const.h"
23 #include "os_account_manager.h"
24 #include "parameter.h"
25 #include "permission_utils.h"
26 #include "preferences_helper.h"
27 #include "ipc_skeleton.h"
28 #include "ringtone_data_manager.h"
29 #include "ringtone_datashare_stub_impl.h"
30 #include "ringtone_file_utils.h"
31 #include "ringtone_language_manager.h"
32 #include "ringtone_log.h"
33 #include "ringtone_scanner_manager.h"
34 #include "ringtone_tracer.h"
35 #include "runtime.h"
36 #include "singleton.h"
37 #include "ringtone_proxy_uri.h"
38 #include "ringtone_fetch_result.h"
39
40 namespace OHOS {
41 namespace AbilityRuntime {
42 using namespace std;
43 using namespace OHOS::AppExecFwk;
44 using namespace OHOS::NativeRdb;
45 using namespace OHOS::Media;
46 using namespace OHOS::DataShare;
47
48 const char RINGTONE_PARAMETER_SCANNER_FIRST_KEY[] = "ringtone.scanner.first";
49 const char RINGTONE_PARAMETER_SCANNER_FIRST_TRUE[] = "true";
50 const char RINGTONE_PARAMETER_SCANNER_FIRST_FALSE[] = "false";
51 const char RINGTONE_PARAMETER_SCANNER_USERID_KEY[] = "ringtone.scanner.userId";
52 const int32_t RINGTONEPARA_SIZE = 64;
53 const std::string OLD_RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH = "/storage/media/local/files/Ringtone";
54 const std::vector<std::string> RINGTONE_OPEN_WRITE_MODE_VECTOR = {
55 { RINGTONE_FILEMODE_WRITEONLY },
56 { RINGTONE_FILEMODE_READWRITE },
57 { RINGTONE_FILEMODE_WRITETRUNCATE },
58 { RINGTONE_FILEMODE_WRITEAPPEND },
59 { RINGTONE_FILEMODE_READWRITETRUNCATE },
60 { RINGTONE_FILEMODE_READWRITEAPPEND },
61 };
62
63 std::map<std::string, std::string> VALID_URI_TO_TABLE {
64 {SIMCARD_SETTING_PATH_URI, SIMCARD_SETTING_TABLE},
65 {RINGTONE_PATH_URI, RINGTONE_TABLE},
66 {VIBRATE_PATH_URI, VIBRATE_TABLE}
67 };
68
Create(const unique_ptr<Runtime> & runtime)69 RingtoneDataShareExtension *RingtoneDataShareExtension::Create(const unique_ptr<Runtime> &runtime)
70 {
71 return new RingtoneDataShareExtension(static_cast<Runtime&>(*runtime));
72 }
73
RingtoneDataShareExtension(Runtime & runtime)74 RingtoneDataShareExtension::RingtoneDataShareExtension(Runtime &runtime) : DataShareExtAbility(), runtime_(runtime) {}
75
~RingtoneDataShareExtension()76 RingtoneDataShareExtension::~RingtoneDataShareExtension()
77 {
78 }
79
Init(const shared_ptr<AbilityLocalRecord> & record,const shared_ptr<OHOSApplication> & application,shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)80 void RingtoneDataShareExtension::Init(const shared_ptr<AbilityLocalRecord> &record,
81 const shared_ptr<OHOSApplication> &application, shared_ptr<AbilityHandler> &handler,
82 const sptr<IRemoteObject> &token)
83 {
84 if ((record == nullptr) || (application == nullptr) || (handler == nullptr) || (token == nullptr)) {
85 RINGTONE_ERR_LOG("RingtoneDataShareExtension::init failed, some object is nullptr");
86 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->KillApplicationSelf();
87 return;
88 }
89 DataShareExtAbility::Init(record, application, handler, token);
90 }
91
OnStart(const AAFwk::Want & want)92 void RingtoneDataShareExtension::OnStart(const AAFwk::Want &want)
93 {
94 RINGTONE_DEBUG_LOG("begin.");
95 Extension::OnStart(want);
96 auto context = AbilityRuntime::Context::GetApplicationContext();
97 if (context == nullptr) {
98 RINGTONE_ERR_LOG("Failed to get context");
99 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->KillApplicationSelf();
100 return;
101 }
102 RINGTONE_INFO_LOG("runtime language %{public}d", runtime_.GetLanguage());
103 auto dataManager = RingtoneDataManager::GetInstance();
104 if (dataManager == nullptr) {
105 RINGTONE_ERR_LOG("Failed to get dataManager");
106 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->KillApplicationSelf();
107 return;
108 }
109 int32_t ret = dataManager->Init(context);
110 if (ret != Media::E_OK) {
111 RINGTONE_ERR_LOG("Failed to init RingtoneData Mgr");
112 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->KillApplicationSelf();
113 return;
114 }
115 dataManager->SetOwner(static_pointer_cast<RingtoneDataShareExtension>(shared_from_this()));
116 auto dfxMgr = DfxManager::GetInstance();
117 dfxMgr->Init(context);
118
119 RingtoneScanner();
120
121 if (RingtoneFileUtils::IsFileExists(OLD_RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH)) {
122 UpdataRdbPathData();
123 }
124
125 RingtoneLanguageManager::GetInstance()->SyncAssetLanguage();
126 RINGTONE_DEBUG_LOG("end.");
127 }
128
OnStop()129 void RingtoneDataShareExtension::OnStop()
130 {
131 RINGTONE_DEBUG_LOG("begin.");
132 auto scannerManager = RingtoneScannerManager::GetInstance();
133 if (scannerManager != nullptr) {
134 scannerManager->Stop();
135 }
136 RingtoneDataManager::GetInstance()->ClearRingtoneDataMgr();
137 RINGTONE_DEBUG_LOG("end.");
138 }
139
OnConnect(const AAFwk::Want & want)140 sptr<IRemoteObject> RingtoneDataShareExtension::OnConnect(const AAFwk::Want &want)
141 {
142 RINGTONE_DEBUG_LOG("begin.");
143 Extension::OnConnect(want);
144 sptr<RingtoneDataShareStubImpl> remoteObject = new (nothrow) RingtoneDataShareStubImpl(
145 static_pointer_cast<RingtoneDataShareExtension>(shared_from_this()),
146 nullptr);
147 if (remoteObject == nullptr) {
148 RINGTONE_ERR_LOG("No memory allocated for DataShareStubImpl");
149 return nullptr;
150 }
151 RINGTONE_DEBUG_LOG("end.");
152 return remoteObject->AsObject();
153 }
154
CheckRingtonePerm(RingtoneDataCommand & cmd,bool isWrite)155 static int32_t CheckRingtonePerm(RingtoneDataCommand &cmd, bool isWrite)
156 {
157 auto err = E_SUCCESS;
158 if (!RingtonePermissionUtils::IsSystemApp() && IPCSkeleton::GetCallingUid() != 0
159 && !RingtonePermissionUtils::IsNativeSAApp()) {
160 RINGTONE_ERR_LOG("RingtoneLibrary should only be called by system applications!");
161 return E_PERMISSION_DENIED;
162 }
163
164 if (isWrite) {
165 err = (RingtonePermissionUtils::CheckCallerPermission(PERM_WRITE_RINGTONE) ? E_SUCCESS : E_PERMISSION_DENIED);
166 }
167
168 return err;
169 }
170
GetValidUriTab(const Uri & uri,string & tab)171 static int32_t GetValidUriTab(const Uri &uri, string &tab)
172 {
173 string uriStr = uri.ToString();
174
175 auto proxyStringPos = uriStr.find(RINGTONE_URI_PROXY_STRING);
176 auto lastSlash = uriStr.find_last_of('/');
177 if (lastSlash != std::string::npos &&
178 proxyStringPos != std::string::npos) {
179 auto tablePos = lastSlash + 1;
180 tab = uriStr.substr(tablePos, proxyStringPos - tablePos);
181 return Media::E_OK;
182 }
183
184 for (const auto &pair : VALID_URI_TO_TABLE) {
185 if (uriStr.find(pair.first) != std::string::npos) {
186 tab = pair.second;
187 return Media::E_OK;
188 }
189 }
190
191 RINGTONE_INFO_LOG("INVALID uri=%{public}s", uriStr.c_str());
192 return E_INVALID_URI;
193 }
194
195 static const std::vector<string> g_ringToneTableFields = {
196 { RINGTONE_COLUMN_TONE_ID },
197 { RINGTONE_COLUMN_DATA },
198 { RINGTONE_COLUMN_SIZE },
199 { RINGTONE_COLUMN_DISPLAY_NAME },
200 { RINGTONE_COLUMN_TITLE },
201 { RINGTONE_COLUMN_MEDIA_TYPE },
202 { RINGTONE_COLUMN_TONE_TYPE },
203 { RINGTONE_COLUMN_MIME_TYPE },
204 { RINGTONE_COLUMN_SOURCE_TYPE },
205 { RINGTONE_COLUMN_DATE_ADDED },
206 { RINGTONE_COLUMN_DATE_MODIFIED },
207 { RINGTONE_COLUMN_DATE_TAKEN },
208 { RINGTONE_COLUMN_DURATION },
209 { RINGTONE_COLUMN_SHOT_TONE_TYPE },
210 { RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE },
211 { RINGTONE_COLUMN_NOTIFICATION_TONE_TYPE },
212 { RINGTONE_COLUMN_NOTIFICATION_TONE_SOURCE_TYPE },
213 { RINGTONE_COLUMN_RING_TONE_TYPE },
214 { RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE },
215 { RINGTONE_COLUMN_ALARM_TONE_TYPE },
216 { RINGTONE_COLUMN_ALARM_TONE_SOURCE_TYPE },
217 { RINGTONE_COLUMN_SCANNER_FLAG },
218 };
219
DumpDataShareValueBucket(const std::vector<string> & tabFields,const DataShareValuesBucket & value)220 void RingtoneDataShareExtension::DumpDataShareValueBucket(const std::vector<string> &tabFields,
221 const DataShareValuesBucket &value)
222 {
223 bool isValid = false;
224 for (auto tab : tabFields) {
225 auto valueObject = value.Get(tab, isValid);
226 if (!isValid) {
227 RINGTONE_INFO_LOG("not set field: %{public}s", tab.c_str());
228 continue;
229 }
230
231 if (std::get_if<std::vector<uint8_t>>(&(valueObject.value))) {
232 auto value = static_cast<std::vector<uint8_t>>(valueObject);
233 RINGTONE_INFO_LOG("field: %{public}s, value=%{public}s",
234 tab.c_str(), value.data());
235 } else if (std::get_if<int64_t>(&(valueObject.value))) {
236 auto value = static_cast<int64_t>(valueObject);
237 RINGTONE_INFO_LOG("field: %{public}s, value=%{public}" PRId64,
238 tab.c_str(), value);
239 } else if (std::get_if<std::string>(&(valueObject.value))) {
240 auto value = static_cast<std::string>(valueObject);
241 RINGTONE_INFO_LOG("field: %{public}s, value=%{public}s",
242 tab.c_str(), value.c_str());
243 } else if (std::get_if<bool>(&(valueObject.value))) {
244 auto value = static_cast<bool>(valueObject);
245 RINGTONE_INFO_LOG("field: %{public}s, value=%{public}d",
246 tab.c_str(), value);
247 } else if (std::get_if<double>(&(valueObject.value))) {
248 auto value = static_cast<double>(valueObject);
249 RINGTONE_INFO_LOG("field: %{public}s, value=%{public}lf",
250 tab.c_str(), value);
251 } else {
252 RINGTONE_INFO_LOG("unkown field: %{public}s type", tab.c_str());
253 }
254 }
255 }
256
UpdataRdbPathData()257 void RingtoneDataShareExtension::UpdataRdbPathData()
258 {
259 RingtoneFileUtils::MoveRingtoneFolder();
260 std::string oldPath;
261 std::string newPath;
262 DataShare::DataShareValuesBucket valuesBucket;
263 Uri uri(RINGTONE_LIBRARY_PROXY_DATA_URI_TONE_FILES);
264
265 DataSharePredicates predicates;
266 const std::string selection = RINGTONE_COLUMN_DATA + " LIKE ? ";
267 std::vector<std::string> selectionArgs = {"%/storage/media/local/files/%"};
268 predicates.SetWhereClause(selection);
269 predicates.SetWhereArgs(selectionArgs);
270
271 vector<string> columns {
272 RINGTONE_COLUMN_DATA
273 };
274 DatashareBusinessError businessError;
275 auto resultSet = Query(uri, predicates, columns, businessError);
276 if (resultSet == nullptr) {
277 return;
278 }
279 auto results = make_unique<RingtoneFetchResult<RingtoneAsset>>(move(resultSet));
280 unique_ptr<RingtoneAsset> ringtoneAsset = results->GetFirstObject();
281 if (ringtoneAsset == nullptr) {
282 RINGTONE_ERR_LOG("ringtoneAsset is nullptr");
283 return;
284 }
285
286 while (ringtoneAsset != nullptr) {
287 oldPath = ringtoneAsset->GetPath();
288 newPath = oldPath;
289 size_t start_pos = 0;
290 if ((start_pos = newPath.find("/storage/media/local/files/Ringtone/")) != std::string::npos) {
291 newPath.replace(start_pos, std::string("/storage/media/local/files/Ringtone").length(),
292 "/data/storage/el2/base/files/Ringtone");
293 }
294
295 if (!RingtoneFileUtils::IsFileExists(newPath)) {
296 RINGTONE_ERR_LOG("the file is not exists, path: %{private}s", newPath.c_str());
297 return;
298 }
299 RINGTONE_INFO_LOG("the file exists, path: %{private}s", newPath.c_str());
300 valuesBucket.Put(RINGTONE_COLUMN_DATA, newPath);
301 Update(uri, predicates, valuesBucket);
302 ringtoneAsset = results->GetNextObject();
303 }
304
305 return;
306 }
307
Insert(const Uri & uri,const DataShareValuesBucket & value)308 int RingtoneDataShareExtension::Insert(const Uri &uri, const DataShareValuesBucket &value)
309 {
310 RINGTONE_DEBUG_LOG("entry, uri=%{public}s", uri.ToString().c_str());
311
312 DumpDataShareValueBucket(g_ringToneTableFields, value);
313
314 string tab("");
315 int err = GetValidUriTab(uri, tab);
316 if (err != Media::E_OK) {
317 return err;
318 }
319
320 RingtoneDataCommand cmd(uri, tab, RingtoneOperationType::INSERT);
321 err = CheckRingtonePerm(cmd, true);
322 if (err < 0) {
323 RINGTONE_ERR_LOG("Check Insert-permission failed, errCode: %{public}d", err);
324 return err;
325 }
326
327 auto ret = RingtoneDataManager::GetInstance()->Insert(cmd, value);
328 return ret;
329 }
330
Update(const Uri & uri,const DataSharePredicates & predicates,const DataShareValuesBucket & value)331 int RingtoneDataShareExtension::Update(const Uri &uri, const DataSharePredicates &predicates,
332 const DataShareValuesBucket &value)
333 {
334 RINGTONE_DEBUG_LOG("entry, uri=%{public}s", uri.ToString().c_str());
335 RINGTONE_DEBUG_LOG("WhereClause=%{public}s", predicates.GetWhereClause().c_str());
336
337 string tab("");
338 int err = GetValidUriTab(uri, tab);
339 if (err != Media::E_OK) {
340 return err;
341 }
342
343 RingtoneDataCommand cmd(uri, tab, RingtoneOperationType::UPDATE);
344 err = CheckRingtonePerm(cmd, false);
345 if (err < 0) {
346 RINGTONE_ERR_LOG("Check Update-permission failed, errCode: %{public}d", err);
347 return err;
348 }
349
350 return RingtoneDataManager::GetInstance()->Update(cmd, value, predicates);
351 }
352
Delete(const Uri & uri,const DataSharePredicates & predicates)353 int RingtoneDataShareExtension::Delete(const Uri &uri, const DataSharePredicates &predicates)
354 {
355 RINGTONE_DEBUG_LOG("entry, uri=%{public}s", uri.ToString().c_str());
356
357 string tab("");
358 int err = GetValidUriTab(uri, tab);
359 if (err != Media::E_OK) {
360 return err;
361 }
362
363 RingtoneDataCommand cmd(uri, tab, RingtoneOperationType::DELETE);
364 err = CheckRingtonePerm(cmd, true);
365 if (err < 0) {
366 RINGTONE_ERR_LOG("Check Delete-permission failed, errCode: %{public}d", err);
367 return err;
368 }
369
370 return RingtoneDataManager::GetInstance()->Delete(cmd, predicates);
371 }
372
Query(const Uri & uri,const DataSharePredicates & predicates,vector<string> & columns,DatashareBusinessError & businessError)373 shared_ptr<DataShareResultSet> RingtoneDataShareExtension::Query(const Uri &uri,
374 const DataSharePredicates &predicates, vector<string> &columns, DatashareBusinessError &businessError)
375 {
376 RINGTONE_DEBUG_LOG("entry, uri=%{public}s", uri.ToString().c_str());
377
378 string tab("");
379 int err = GetValidUriTab(uri, tab);
380 if (err != Media::E_OK) {
381 return nullptr;
382 }
383
384 RingtoneDataCommand cmd(uri, tab, RingtoneOperationType::QUERY);
385 err = CheckRingtonePerm(cmd, false);
386 if (err < 0) {
387 businessError.SetCode(err);
388 RINGTONE_ERR_LOG("Check Query-permission failed, errCode: %{public}d", err);
389 return nullptr;
390 }
391
392 int errCode = businessError.GetCode();
393 auto queryResultSet = RingtoneDataManager::GetInstance()->Query(cmd, columns, predicates, errCode);
394 businessError.SetCode(to_string(errCode));
395 if (queryResultSet == nullptr) {
396 RINGTONE_ERR_LOG("queryResultSet is nullptr! errCode: %{public}d", errCode);
397 return nullptr;
398 }
399 shared_ptr<DataShareResultSet> resultSet = make_shared<DataShareResultSet>(queryResultSet);
400 return resultSet;
401 }
402
OpenFile(const Uri & uri,const string & mode)403 int RingtoneDataShareExtension::OpenFile(const Uri &uri, const string &mode)
404 {
405 RINGTONE_DEBUG_LOG("entry, uri=%{public}s, mode=%{public}s",
406 uri.ToString().c_str(), mode.c_str());
407
408 string tab("");
409 int err = GetValidUriTab(uri, tab);
410 if (err != Media::E_OK) {
411 return err;
412 }
413
414 RingtoneDataCommand cmd(uri, tab, RingtoneOperationType::OPEN);
415 string unifyMode = mode;
416 transform(unifyMode.begin(), unifyMode.end(), unifyMode.begin(), ::tolower);
417
418 bool isWrite = false;
419 auto iter = find(RINGTONE_OPEN_WRITE_MODE_VECTOR.begin(), RINGTONE_OPEN_WRITE_MODE_VECTOR.end(), unifyMode);
420 if (iter != RINGTONE_OPEN_WRITE_MODE_VECTOR.end()) {
421 isWrite = true;
422 }
423 err = CheckRingtonePerm(cmd, isWrite);
424 if (err == E_PERMISSION_DENIED) {
425 RINGTONE_ERR_LOG("OpenFile denied, errCode: %{public}d", err);
426 return err;
427 }
428 return RingtoneDataManager::GetInstance()->OpenFile(cmd, unifyMode);
429 }
430
GetUserId()431 int32_t RingtoneDataShareExtension::GetUserId()
432 {
433 RINGTONE_INFO_LOG("GetUserID Start.");
434 int32_t userId = 0;
435 std::vector<int> activeIds;
436 int ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeIds);
437 if (ret != 0) {
438 RINGTONE_ERR_LOG("QueryActiveOsAccountIds failed ret:%{public}d", ret);
439 return userId;
440 }
441 if (activeIds.empty()) {
442 RINGTONE_ERR_LOG("QueryActiveOsAccountIds activeIds empty");
443 return userId;
444 }
445 userId = activeIds[0];
446 RINGTONE_INFO_LOG("GetUserID End, userId: %{private}d", userId);
447 return userId;
448 }
449
IdExists(const std::string & ids,int32_t id)450 bool RingtoneDataShareExtension::IdExists(const std::string &ids, int32_t id)
451 {
452 RINGTONE_INFO_LOG("IdExists Start.");
453 if (ids.empty()) {
454 return false;
455 }
456
457 size_t pos = 0;
458 std::string idStr = std::to_string(id);
459
460 while ((pos = ids.find(idStr, pos)) != std::string::npos) {
461 bool startPos = (pos == 0) || (ids[pos - 1] == ' ');
462 bool endPos = (pos + idStr.length() == ids.length()) || (ids[pos + idStr.length()] == ' ');
463 if (startPos && endPos) {
464 return true;
465 }
466 pos += idStr.length();
467 }
468 RINGTONE_INFO_LOG("IdExists End.");
469 return false;
470 }
471
CheckCurrentUser()472 bool RingtoneDataShareExtension::CheckCurrentUser()
473 {
474 RINGTONE_INFO_LOG("CheckCurrentUser Start.");
475 char paramValue[RINGTONEPARA_SIZE] = {0};
476 GetParameter(RINGTONE_PARAMETER_SCANNER_USERID_KEY, "", paramValue, RINGTONEPARA_SIZE);
477 std::string ids(paramValue);
478 RINGTONE_INFO_LOG("GetParameter end, paramValue: %{private}s .", ids.c_str());
479 int32_t currentUserId = GetUserId();
480 if (IdExists(ids, currentUserId)) {
481 return true;
482 }
483 if (!ids.empty() && ids.back() != ' ') {
484 ids += " ";
485 }
486 ids += std::to_string(currentUserId);
487 RINGTONE_INFO_LOG("CurrentUserIds: %{private}s .", ids.c_str());
488 const char* cstr = ids.c_str();
489 int result = SetParameter(RINGTONE_PARAMETER_SCANNER_USERID_KEY, cstr);
490 RINGTONE_INFO_LOG("CheckCurrentUser End. SetParameter end, result: %{public}d", result);
491 return false;
492 }
493
RingtoneScanner()494 void RingtoneDataShareExtension::RingtoneScanner()
495 {
496 RingtoneTracer tracer;
497 tracer.Start("Ringtone Scanner");
498 RINGTONE_INFO_LOG("Ringtone Scanner Start.");
499 RingtoneFileUtils::AccessRingtoneDir();
500 // ringtone scan
501 char paramValue[RINGTONEPARA_SIZE] = {0};
502 bool currentFlag = CheckCurrentUser();
503 GetParameter(RINGTONE_PARAMETER_SCANNER_FIRST_KEY, "", paramValue, RINGTONEPARA_SIZE);
504 if (!currentFlag && strcmp(paramValue, RINGTONE_PARAMETER_SCANNER_FIRST_TRUE) == 0) {
505 int result = SetParameter(RINGTONE_PARAMETER_SCANNER_FIRST_KEY, RINGTONE_PARAMETER_SCANNER_FIRST_FALSE);
506 RINGTONE_INFO_LOG("CheckCurrentUser SetParameter end, result: %{public}d", result);
507 }
508 GetParameter(RINGTONE_PARAMETER_SCANNER_FIRST_KEY, "", paramValue, RINGTONEPARA_SIZE);
509 std::string parameter(paramValue);
510 RINGTONE_INFO_LOG("GetParameter end, paramValue: %{public}s .", parameter.c_str());
511 if (strcmp(paramValue, RINGTONE_PARAMETER_SCANNER_FIRST_FALSE) == 0) {
512 RingtoneScannerManager::GetInstance()->Start(false);
513 int result = SetParameter(RINGTONE_PARAMETER_SCANNER_FIRST_KEY, RINGTONE_PARAMETER_SCANNER_FIRST_TRUE);
514 RINGTONE_INFO_LOG("SetParameter end, result: %{public}d", result);
515 }
516 RINGTONE_INFO_LOG("Ringtone Scanner End.");
517 }
518
RingtoneDataShareCreator(const unique_ptr<Runtime> & runtime)519 static DataShare::DataShareExtAbility *RingtoneDataShareCreator(const unique_ptr<Runtime> &runtime)
520 {
521 RINGTONE_DEBUG_LOG("entry");
522 return RingtoneDataShareExtension::Create(runtime);
523 }
524
RegisterDataShareCreator()525 __attribute__((constructor)) void RegisterDataShareCreator()
526 {
527 RINGTONE_ERR_LOG("entry");
528 DataShare::DataShareExtAbility::SetCreator(RingtoneDataShareCreator);
529
530 RINGTONE_ERR_LOG("End");
531 }
532 } // namespace AbilityRuntime
533 } // namespace OHOS
534