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