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 <fstream>
17 #include <vector>
18
19 #include "dualfwk_conf_loader.h"
20 #include "ringtone_errno.h"
21 #include "ringtone_file_utils.h"
22 #include "ringtone_restore_db_utils.h"
23 #include "directory_ex.h"
24
25 namespace OHOS {
26 namespace Media {
27
28 static const std::string SETTINGS_DATA_URI_BASE =
29 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_";
30 static const std::string SETTINGS_DATA_FIELD_KEY = "KEYWORD";
31 static const std::string SETTINGS_DATA_FIELD_VAL = "VALUE";
32 static std::vector<std::string> SETTINGS_COLUMNS = {SETTINGS_DATA_FIELD_VAL};
33 static const int DEFAULT_USERID = 100;
34
DualFwkConfLoader()35 DualFwkConfLoader::DualFwkConfLoader() {}
36
Init()37 int32_t DualFwkConfLoader::Init()
38 {
39 DataShare::CreateOptions options;
40
41 int userId = 0;
42 if (!RingtoneRestoreDbUtils::GetUserID(userId)) {
43 RINGTONE_DEBUG_LOG("Failed to get userId, using DEFAULT_USERID=%{public}d", DEFAULT_USERID);
44 userId = DEFAULT_USERID;
45 }
46 settingsDataUri_ = SETTINGS_DATA_URI_BASE + std::to_string(userId);
47 RINGTONE_DEBUG_LOG("Getting data share helper with SETTINGS_DATA_URI = %{public}s", settingsDataUri_.c_str());
48
49 dataShareHelper_ = DataShare::DataShareHelper::Creator(settingsDataUri_, options);
50 if (dataShareHelper_ == nullptr) {
51 RINGTONE_WARN_LOG("dataShareHelper_ is null, failed to get data share helper");
52 return E_ERR;
53 }
54
55 RINGTONE_INFO_LOG("Successfully initialized.");
56 return E_OK;
57 }
58
GetSound(const std::string & line)59 static std::string GetSound(const std::string &line)
60 {
61 std::string tag = "sound=\"";
62 auto lenTag = tag.size();
63 auto positionOfTag = line.find(tag);
64 if (positionOfTag == std::string::npos) {
65 return "";
66 }
67 auto positionOfQuote = line.substr(positionOfTag + lenTag).find("\"");
68 if (positionOfQuote == std::string::npos) {
69 return "";
70 }
71 return line.substr(positionOfTag + lenTag, positionOfQuote);
72 }
73
ParseBackupFile(const std::string & backupFile,const std::vector<std::string> & keys,std::map<std::string,std::string> & results)74 static int32_t ParseBackupFile(const std::string &backupFile, const std::vector<std::string> &keys,
75 std::map<std::string, std::string> &results)
76 {
77 RINGTONE_INFO_LOG("parse backupfile %{public}s uid=%{public}d", backupFile.c_str(), getuid());
78 std::string realPath;
79 if (!PathToRealPath(backupFile, realPath)) {
80 RINGTONE_ERR_LOG("the file not exists path: %{private}s", backupFile.c_str());
81 return E_INVALID_PATH;
82 }
83
84 std::ifstream fs(realPath);
85 if (!fs.good()) {
86 RINGTONE_ERR_LOG("failed to open file %{private}s", realPath.c_str());
87 return E_ERR;
88 }
89
90 std::string line;
91 while (std::getline(fs, line)) {
92 for (const auto &key : keys) {
93 auto pos = line.find(key);
94 if (pos == std::string::npos) {
95 continue;
96 }
97 std::string value = GetSound(line);
98 if (value.size() > 0) {
99 results.emplace(key, value);
100 }
101 }
102 }
103 return E_SUCCESS;
104 }
105
Load(DualFwkConf & conf,const RestoreSceneType & type,const std::string & backupFile)106 int32_t DualFwkConfLoader::Load(DualFwkConf &conf, const RestoreSceneType &type, const std::string &backupFile)
107 {
108 if (dataShareHelper_ == nullptr) {
109 RINGTONE_ERR_LOG("DualFwkConfLoader is not initialized successfully");
110 return E_ERR;
111 }
112 std::map<std::string, std::string> backupConfigs;
113 if (ParseBackupFile(backupFile, {"mms_sim1_channel", "mms_sim2_channel"}, backupConfigs) != E_SUCCESS) {
114 RINGTONE_WARN_LOG("Failed to parse backup file %{public}s", backupFile.c_str());
115 }
116
117 if (type == RestoreSceneType::RESTORE_SCENE_TYPE_DUAL_CLONE) {
118 RINGTONE_INFO_LOG("Load configurations for RestoreSceneType::RESTORE_SCENE_TYPE_DUAL_CLONE");
119 conf.notificationSoundPath = GetConf("notification_sound");
120 conf.ringtonePath = GetConf("ringtone_path");
121 conf.ringtone2Path = GetConf("ringtone2_path");
122 conf.alarmAlertPath = GetConf("alarm_alert");
123 conf.messagePath = GetConf("message_path");
124 conf.messageSub1 = GetConf("message_sub1");
125 conf.messagePath = backupConfigs["mms_sim1_channel"];
126 conf.messageSub1 = backupConfigs["mms_sim2_channel"];
127 } else {
128 RINGTONE_INFO_LOG("Load configurations for RestoreSceneType::RESTORE_SCENE_TYPE_DUAL_UPGRADE");
129 conf.notificationSoundPath = GetConf("notification_sound_path");
130 conf.ringtonePath = GetConf("ringtone_path");
131 conf.ringtone2Path = GetConf("ringtone2_path");
132 conf.alarmAlertPath = GetConf("alarm_alert_path");
133 conf.messagePath = GetConf("message_path");
134 conf.messageSub1 = GetConf("message_sub1");
135 }
136
137 return E_OK;
138 }
139
ShowConf(const DualFwkConf & conf)140 void DualFwkConfLoader::ShowConf(const DualFwkConf &conf)
141 {
142 RINGTONE_DEBUG_LOG("===================================================");
143 RINGTONE_DEBUG_LOG("conf.notificationSoundPath = %{public}s", conf.notificationSoundPath.c_str());
144 RINGTONE_DEBUG_LOG("conf.ringtonePath = %{public}s", conf.ringtonePath.c_str());
145 RINGTONE_DEBUG_LOG("conf.ringtone2Path = %{public}s", conf.ringtone2Path.c_str());
146 RINGTONE_DEBUG_LOG("conf.alarmAlertPath = %{public}s", conf.alarmAlertPath.c_str());
147 RINGTONE_DEBUG_LOG("conf.messagePath = %{public}s", conf.messagePath.c_str());
148 RINGTONE_DEBUG_LOG("conf.messageSub1 = %{public}s", conf.messageSub1.c_str());
149 RINGTONE_DEBUG_LOG("===================================================");
150 }
151
GetConf(const std::string & key)152 std::string DualFwkConfLoader::GetConf(const std::string &key)
153 {
154 DataShare::DataSharePredicates dataSharePredicates;
155 dataSharePredicates.EqualTo(SETTINGS_DATA_FIELD_KEY, key);
156 Uri uri(settingsDataUri_);
157 auto resultSet = dataShareHelper_->Query(uri, dataSharePredicates, SETTINGS_COLUMNS);
158 if (resultSet == nullptr) {
159 RINGTONE_DEBUG_LOG("resultSet is null, failed to get value of key = %{public}s", key.c_str());
160 return "";
161 }
162
163 int32_t numRows = 0;
164 resultSet->GetRowCount(numRows);
165 RINGTONE_INFO_LOG("%{public}d records found with key = %{public}s", numRows, key.c_str());
166 if (numRows == 0) {
167 RINGTONE_DEBUG_LOG("no record at key = %{public}s, returning an empty string.", key.c_str());
168 return "";
169 }
170 int32_t columnIndex = 0;
171 int32_t rowNumber = 0;
172 resultSet->GoToRow(rowNumber);
173 std::string valueResult = "";
174 int32_t ret = resultSet->GetString(columnIndex, valueResult);
175 if (ret != 0) {
176 RINGTONE_DEBUG_LOG("failed to get string, returning an empty string.");
177 } else {
178 RINGTONE_DEBUG_LOG("valueResult = %{public}s", valueResult.c_str());
179 }
180 return valueResult;
181 }
182 } // namespace Media
183 } // namespace OHOS