• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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