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 "ringtone_utils.h"
17
18#include <securec.h>
19
20#include "parameter.h"
21#include "directory_ex.h"
22#include "dfx_const.h"
23#include "rdb_sql_utils.h"
24#include "ringtone_errno.h"
25#include "ringtone_log.h"
26#include "ringtone_type.h"
27#include "ringtone_db_const.h"
28#include "ringtone_rdb_callbacks.h"
29#include "preferences_helper.h"
30#include "rdb_store_config.h"
31
32namespace OHOS {
33namespace Media {
34using namespace std;
35const char RINGTONE_PARAMETER_SCANNER_COMPLETED_KEY[] = "ringtone.scanner.completed";
36const int RINGTONE_PARAMETER_SCANNER_COMPLETED_TRUE = 1;
37const int RINGTONE_PARAMETER_SCANNER_COMPLETED_FALSE = 0;
38static const int32_t SYSPARA_SIZE = 128;
39static const int32_t NO_NEED_SCANNER = 1;
40static const int32_t RDB_AREA_EL2 = 2;
41
42std::string RingtoneUtils::ReplaceAll(std::string str, const std::string &oldValue, const std::string &newValue)
43{
44    for (std::string::size_type pos(0); pos != std::string::npos; pos += newValue.length()) {
45        if ((pos = str.find(oldValue, pos)) != std::string::npos) {
46            str.replace(pos, oldValue.length(), newValue);
47        } else {
48            break;
49        }
50    }
51    return str;
52}
53
54std::map<int, std::string> RingtoneUtils::GetDefaultSystemtoneInfo()
55{
56    map<int, string> defaultSystemtoneInfo;
57    char paramValue[SYSPARA_SIZE] = {0};
58    GetParameter(PARAM_RINGTONE_SETTING_RINGTONE, "", paramValue, SYSPARA_SIZE);
59    if (strlen(paramValue) > 0) {
60        defaultSystemtoneInfo.insert(make_pair(DEFAULT_RING_TYPE_SIM_CARD_1, string(paramValue)));
61    }
62
63    if (memset_s(paramValue, sizeof(paramValue), 0, sizeof(paramValue)) == 0) {
64        GetParameter(PARAM_RINGTONE_SETTING_RINGTONE2, "", paramValue, SYSPARA_SIZE);
65        if (strlen(paramValue) > 0) {
66            defaultSystemtoneInfo.insert(make_pair(DEFAULT_RING_TYPE_SIM_CARD_2, string(paramValue)));
67        }
68    }
69
70    if (memset_s(paramValue, sizeof(paramValue), 0, sizeof(paramValue)) == 0) {
71        GetParameter(PARAM_RINGTONE_SETTING_SHOT, "", paramValue, SYSPARA_SIZE);
72        if (strlen(paramValue) > 0) {
73            defaultSystemtoneInfo.insert(make_pair(DEFAULT_SHOT_TYPE_SIM_CARD_1, string(paramValue)));
74        }
75    }
76
77    if (memset_s(paramValue, sizeof(paramValue), 0, sizeof(paramValue)) == 0) {
78        GetParameter(PARAM_RINGTONE_SETTING_SHOT2, "", paramValue, SYSPARA_SIZE);
79        if (strlen(paramValue) > 0) {
80            defaultSystemtoneInfo.insert(make_pair(DEFAULT_SHOT_TYPE_SIM_CARD_2, string(paramValue)));
81        }
82    }
83
84    if (memset_s(paramValue, sizeof(paramValue), 0, sizeof(paramValue)) == 0) {
85        GetParameter(PARAM_RINGTONE_SETTING_NOTIFICATIONTONE, "", paramValue, SYSPARA_SIZE);
86        if (strlen(paramValue) > 0) {
87            defaultSystemtoneInfo.insert(make_pair(DEFAULT_NOTIFICATION_TYPE, string(paramValue)));
88        }
89    }
90
91    if (memset_s(paramValue, sizeof(paramValue), 0, sizeof(paramValue)) == 0) {
92        GetParameter(PARAM_RINGTONE_SETTING_ALARM, "", paramValue, SYSPARA_SIZE);
93        if (strlen(paramValue) > 0) {
94            defaultSystemtoneInfo.insert(make_pair(DEFAULT_ALARM_TYPE, string(paramValue)));
95        }
96    }
97
98    return defaultSystemtoneInfo;
99}
100
101int32_t RingtoneUtils::ChecMoveDb()
102{
103    auto ret = RingtoneUtils::CheckNeedScanner(COMMON_XML_EL1);
104    if (ret == NO_NEED_SCANNER) {
105        RINGTONE_INFO_LOG("no need to scanner el1");
106        return NO_NEED_SCANNER;
107    } else if (ret == E_ERR) {
108        RINGTONE_INFO_LOG("open el1 xml error");
109        return E_ERR;
110    }
111
112    ret = RingtoneUtils::CheckNeedScanner(DFX_COMMON_XML);
113    if (ret == E_ERR) {
114        RINGTONE_INFO_LOG("open el2 xml error");
115        return E_ERR;
116    } else if (ret == E_OK) {
117        RINGTONE_INFO_LOG("need to scanner el2");
118        return E_OK;
119    }
120    if (!RingtoneUtils::MoveEL2DBToEL1DB()) {
121        RINGTONE_INFO_LOG("move error");
122        return E_ERR;
123    }
124    RingtoneUtils::SetMoveEL2DBToEL1();
125    return E_OK;
126}
127
128int32_t RingtoneUtils::CheckNeedScanner(const std::string &xmlFilePath)
129{
130    int32_t errCode;
131    shared_ptr<NativePreferences::Preferences> prefs =
132        NativePreferences::PreferencesHelper::GetPreferences(xmlFilePath, errCode);
133    if (!prefs) {
134        RINGTONE_ERR_LOG("get el1 preferences error: %{public}d", errCode);
135        return E_ERR;
136    }
137    int isCompleted = prefs->GetInt(RINGTONE_PARAMETER_SCANNER_COMPLETED_KEY,
138        RINGTONE_PARAMETER_SCANNER_COMPLETED_FALSE);
139    if (!isCompleted) {
140        return E_OK;
141    }
142    return NO_NEED_SCANNER;
143}
144
145bool RingtoneUtils::MoveEL2DBToEL1DB()
146{
147    int32_t errCode = 0;
148    RingtoneDataCallBack rdbDataCallBack;
149    NativeRdb::RdbStoreConfig config {""};
150    config.SetName(RINGTONE_LIBRARY_DB_NAME);
151    string realPath = NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(RINGTONE_LIBRARY_DB_PATH,
152        RINGTONE_LIBRARY_DB_NAME, errCode);
153    config.SetPath(move(realPath));
154    config.SetBundleName(RINGTONE_BUNDLE_NAME);
155    config.SetArea(RDB_AREA_EL2);
156    config.SetSecurityLevel(NativeRdb::SecurityLevel::S3);
157    auto rdbStore = NativeRdb::RdbHelper::GetRdbStore(config, RINGTONE_RDB_VERSION,
158        rdbDataCallBack, errCode);
159    if (rdbStore == nullptr) {
160        RINGTONE_ERR_LOG("GetRdbStore is failed , errCode=%{public}d", errCode);
161        return false;
162    }
163    //el2 rdb success
164    realPath = NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(RINGTONE_LIBRARY_DB_PATH_EL1,
165        RINGTONE_LIBRARY_DB_NAME, errCode);
166    RINGTONE_ERR_LOG("rdb Backup, realPath = %{public}s", realPath.c_str());
167    auto ret = rdbStore->Backup(realPath);
168    RINGTONE_ERR_LOG("rdb Backup, ret = %{public}d", ret);
169    return true;
170}
171
172bool RingtoneUtils::SetMoveEL2DBToEL1()
173{
174    int32_t errCode;
175    shared_ptr<NativePreferences::Preferences> prefs =
176        NativePreferences::PreferencesHelper::GetPreferences(COMMON_XML_EL1, errCode);
177    if (!prefs) {
178        RINGTONE_ERR_LOG("get el1 preferences error: %{public}d", errCode);
179        return false;
180    }
181    prefs->PutInt(RINGTONE_PARAMETER_SCANNER_COMPLETED_KEY, RINGTONE_PARAMETER_SCANNER_COMPLETED_TRUE);
182    prefs->FlushSync();
183    return true;
184}
185} // namespace Media
186} // namespace OHOS
187