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_rdb_callbacks.h"
17
18 #include <sys/stat.h>
19
20 #include "rdb_sql_utils.h"
21 #include "ringtone_errno.h"
22 #include "ringtone_log.h"
23 #include "ringtone_db_const.h"
24 #include "ringtone_file_utils.h"
25 #include "ringtone_mimetype_utils.h"
26 #include "ringtone_utils.h"
27 #include "result_set_utils.h"
28 #include "preferences_helper.h"
29 #include "dfx_const.h"
30
31 namespace OHOS {
32 namespace Media {
33 using namespace std;
34
35 const string DEFAULT_MIME_TYPE = "application/octet-stream";
36 static const char RINGTONE_PARAMETER_SCANNER_COMPLETED_KEY[] = "ringtone.scanner.completed";
37 static const int RINGTONE_PARAMETER_SCANNER_COMPLETED_FALSE = 0;
38
39 const std::string CREATE_RINGTONE_TABLE = "CREATE TABLE IF NOT EXISTS " + RINGTONE_TABLE + "(" +
40 RINGTONE_COLUMN_TONE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
41 RINGTONE_COLUMN_DATA + " TEXT , " +
42 RINGTONE_COLUMN_SIZE + " BIGINT DEFAULT 0, " +
43 RINGTONE_COLUMN_DISPLAY_NAME + " TEXT , " +
44 RINGTONE_COLUMN_TITLE + " TEXT , " +
45 RINGTONE_COLUMN_MEDIA_TYPE + " INT DEFAULT 0, " +
46 RINGTONE_COLUMN_TONE_TYPE + " INT DEFAULT 0, " +
47 RINGTONE_COLUMN_MIME_TYPE + " TEXT , " +
48 RINGTONE_COLUMN_SOURCE_TYPE + " INT DEFAULT 0, " +
49 RINGTONE_COLUMN_DATE_ADDED + " BIGINT DEFAULT 0, " +
50 RINGTONE_COLUMN_DATE_MODIFIED + " BIGINT DEFAULT 0, " +
51 RINGTONE_COLUMN_DATE_TAKEN + " BIGINT DEFAULT 0, " +
52 RINGTONE_COLUMN_DURATION + " INT DEFAULT 0, " +
53 RINGTONE_COLUMN_SHOT_TONE_TYPE + " INT DEFAULT 0, " +
54 RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE + " INT DEFAULT 0, " +
55 RINGTONE_COLUMN_NOTIFICATION_TONE_TYPE + " INT DEFAULT 0, " +
56 RINGTONE_COLUMN_NOTIFICATION_TONE_SOURCE_TYPE + " INT DEFAULT 0, " +
57 RINGTONE_COLUMN_RING_TONE_TYPE + " INT DEFAULT 0, " +
58 RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE + " INT DEFAULT 0, " +
59 RINGTONE_COLUMN_ALARM_TONE_TYPE + " INT DEFAULT 0, " +
60 RINGTONE_COLUMN_ALARM_TONE_SOURCE_TYPE + " INT DEFAULT 0, " +
61 RINGTONE_COLUMN_DISPLAY_LANGUAGE_TYPE + " TEXT " + ")";
62
63 const std::string CREATE_PRELOAD_CONF_TABLE = "CREATE TABLE IF NOT EXISTS " + PRELOAD_CONFIG_TABLE + "(" +
64 PRELOAD_CONFIG_COLUMN_RING_TONE_TYPE + " INTEGER PRIMARY KEY," +
65 PRELOAD_CONFIG_COLUMN_TONE_ID + " INTEGER ," +
66 PRELOAD_CONFIG_COLUMN_DISPLAY_NAME + " TEXT " + ")";
67
68 const std::string INIT_PRELOAD_CONF_TABLE = "INSERT OR IGNORE INTO " + PRELOAD_CONFIG_TABLE + " (" +
69 PRELOAD_CONFIG_COLUMN_RING_TONE_TYPE + ") VALUES (1), (2), (3), (4), (5), (6);";
70
71 const std::string CREATE_SIMCARD_SETTING_TABLE = "CREATE TABLE IF NOT EXISTS " + SIMCARD_SETTING_TABLE + "(" +
72 SIMCARD_SETTING_COLUMN_MODE + " INTEGER ," +
73 SIMCARD_SETTING_COLUMN_RINGTONE_TYPE + " INTEGER ," +
74 SIMCARD_SETTING_COLUMN_TONE_FILE + " TEXT ," +
75 SIMCARD_SETTING_COLUMN_VIBRATE_FILE + " TEXT ," +
76 SIMCARD_SETTING_COLUMN_VIBRATE_MODE + " INTEGER ," +
77 SIMCARD_SETTING_COLUMN_RING_MODE + " INTEGER ," +
78 " PRIMARY KEY (" + SIMCARD_SETTING_COLUMN_MODE + ", " + SIMCARD_SETTING_COLUMN_RINGTONE_TYPE + "))";
79
80 const std::string INIT_SIMCARD_SETTING_TABLE = "INSERT OR IGNORE INTO " + SIMCARD_SETTING_TABLE + " (" +
81 SIMCARD_SETTING_COLUMN_MODE + ", " +
82 SIMCARD_SETTING_COLUMN_RINGTONE_TYPE + ") VALUES (1, 0), (1, 1), (1, 2), (1, 3), \
83 (2, 0), (2, 1), (2, 2), (2, 3), \
84 (3, 0), (3, 1), (3, 2), (3, 3);";
85
86 const std::string CREATE_VIBRATE_TABLE = "CREATE TABLE IF NOT EXISTS " + VIBRATE_TABLE + "(" +
87 VIBRATE_COLUMN_VIBRATE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
88 VIBRATE_COLUMN_DATA + " TEXT , " +
89 VIBRATE_COLUMN_SIZE + " BIGINT DEFAULT 0, " +
90 VIBRATE_COLUMN_DISPLAY_NAME + " TEXT , " +
91 VIBRATE_COLUMN_TITLE + " TEXT , " +
92 VIBRATE_COLUMN_DISPLAY_LANGUAGE + " TEXT , " +
93 VIBRATE_COLUMN_VIBRATE_TYPE + " INT DEFAULT 0, " +
94 VIBRATE_COLUMN_SOURCE_TYPE + " INT DEFAULT 0, " +
95 VIBRATE_COLUMN_DATE_ADDED + " BIGINT DEFAULT 0, " +
96 VIBRATE_COLUMN_DATE_MODIFIED + " BIGINT DEFAULT 0, " +
97 VIBRATE_COLUMN_DATE_TAKEN + " BIGINT DEFAULT 0, " +
98 VIBRATE_COLUMN_PLAY_MODE + " INT DEFAULT 0 " + ")";
99
100
101 static const vector<string> g_initSqls = {
102 CREATE_RINGTONE_TABLE,
103 CREATE_VIBRATE_TABLE,
104 CREATE_SIMCARD_SETTING_TABLE,
105 INIT_SIMCARD_SETTING_TABLE,
106 CREATE_PRELOAD_CONF_TABLE,
107 INIT_PRELOAD_CONF_TABLE
108 };
109
RingtoneDataCallBack(void)110 RingtoneDataCallBack::RingtoneDataCallBack(void)
111 {
112 }
113
~RingtoneDataCallBack(void)114 RingtoneDataCallBack::~RingtoneDataCallBack(void)
115 {
116 }
117
InitSql(NativeRdb::RdbStore & store)118 int32_t RingtoneDataCallBack::InitSql(NativeRdb::RdbStore &store)
119 {
120 for (const string &sqlStr : g_initSqls) {
121 if (store.ExecuteSql(sqlStr) != NativeRdb::E_OK) {
122 RINGTONE_ERR_LOG("Failed to execute sql");
123 return NativeRdb::E_ERROR;
124 }
125 }
126 return NativeRdb::E_OK;
127 }
128
OnCreate(NativeRdb::RdbStore & store)129 int32_t RingtoneDataCallBack::OnCreate(NativeRdb::RdbStore &store)
130 {
131 if (InitSql(store) != NativeRdb::E_OK) {
132 RINGTONE_DEBUG_LOG("Failed to init sql");
133 return NativeRdb::E_ERROR;
134 }
135
136 RingtoneFileUtils::CreateRingtoneDir();
137 return NativeRdb::E_OK;
138 }
139
ExecSqls(const vector<string> & sqls,NativeRdb::RdbStore & store)140 static void ExecSqls(const vector<string> &sqls, NativeRdb::RdbStore &store)
141 {
142 int32_t err = NativeRdb::E_OK;
143 for (const auto &sql : sqls) {
144 err = store.ExecuteSql(sql);
145 if (err != NativeRdb::E_OK) {
146 RINGTONE_ERR_LOG("Failed to exec: %{private}s", sql.c_str());
147 continue;
148 }
149 }
150 }
151
AddDisplayLanguageColumn(NativeRdb::RdbStore & store)152 static void AddDisplayLanguageColumn(NativeRdb::RdbStore &store)
153 {
154 const vector<string> sqls = {
155 "ALTER TABLE " + RINGTONE_TABLE + " ADD COLUMN " + RINGTONE_COLUMN_DISPLAY_LANGUAGE_TYPE + " TEXT",
156 };
157 RINGTONE_INFO_LOG("Add display language column");
158 ExecSqls(sqls, store);
159 }
160
UpdateMimeType(NativeRdb::RdbStore & store)161 static void UpdateMimeType(NativeRdb::RdbStore &store)
162 {
163 RINGTONE_INFO_LOG("Update MimeType Begin");
164 RingtoneMimeTypeUtils::InitMimeTypeMap();
165 const string sql = "SELECT * FROM " + RINGTONE_TABLE;
166 auto resultSet = store.QuerySql(sql);
167 if (resultSet == nullptr) {
168 RINGTONE_ERR_LOG("error query sql %{public}s", sql.c_str());
169 return;
170 }
171 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
172 std::string mimeType = GetStringVal(RINGTONE_COLUMN_MIME_TYPE, resultSet);
173 if (mimeType != DEFAULT_MIME_TYPE) {
174 continue;
175 }
176 string displayName = GetStringVal(RINGTONE_COLUMN_DISPLAY_NAME, resultSet);
177 int32_t toneid = GetInt32Val(RINGTONE_COLUMN_TONE_ID, resultSet);
178 std::string extension = RingtoneFileUtils::GetFileExtension(displayName);
179 mimeType = RingtoneMimeTypeUtils::GetMimeTypeFromExtension(extension);
180 int32_t mime = RingtoneMimeTypeUtils::GetMediaTypeFromMimeType(mimeType);
181 RINGTONE_INFO_LOG("extension: %{public}s, mimeType: %{public}s, toneid: %{public}d mime: %{public}d",
182 extension.c_str(), mimeType.c_str(), toneid, mime);
183
184 NativeRdb::ValuesBucket values;
185 values.PutString(RINGTONE_COLUMN_MIME_TYPE, mimeType);
186 values.PutInt(RINGTONE_COLUMN_MEDIA_TYPE, mime);
187 NativeRdb::AbsRdbPredicates absRdbPredicates(RINGTONE_TABLE);
188 absRdbPredicates.EqualTo(RINGTONE_COLUMN_TONE_ID, toneid);
189 int32_t changedRows;
190 int32_t result = store.Update(changedRows, values, absRdbPredicates);
191 if (result != E_OK || changedRows <= 0) {
192 RINGTONE_ERR_LOG("Update operation failed. Result %{public}d. Updated %{public}d", result, changedRows);
193 }
194 }
195 resultSet->Close();
196 }
197
AddPreloadConfTable(NativeRdb::RdbStore & store)198 static void AddPreloadConfTable(NativeRdb::RdbStore &store)
199 {
200 const vector<string> sqls = {
201 CREATE_PRELOAD_CONF_TABLE,
202 INIT_PRELOAD_CONF_TABLE
203 };
204 RINGTONE_INFO_LOG("Add preload config table");
205 ExecSqls(sqls, store);
206 }
207
UpdateDefaultSystemTone(NativeRdb::RdbStore & store)208 static void UpdateDefaultSystemTone(NativeRdb::RdbStore &store)
209 {
210 RINGTONE_INFO_LOG("setting system tone begin");
211 auto infos = RingtoneUtils::GetDefaultSystemtoneInfo();
212 for (auto info : infos) {
213 const string querySql = "SELECT tone_id FROM ToneFiles WHERE display_name = "s + "\"" + info.second + "\"";
214 auto resultSet = store.QuerySql(querySql);
215 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
216 RINGTONE_ERR_LOG("Update operation failed. no resultSet");
217 continue;
218 }
219
220 int32_t tone_id = GetInt32Val("tone_id", resultSet);
221 NativeRdb::ValuesBucket values;
222 values.PutString(PRELOAD_CONFIG_COLUMN_DISPLAY_NAME, info.second);
223 values.PutInt(PRELOAD_CONFIG_COLUMN_TONE_ID, tone_id);
224 NativeRdb::AbsRdbPredicates absRdbPredicates(PRELOAD_CONFIG_TABLE);
225 absRdbPredicates.EqualTo(PRELOAD_CONFIG_COLUMN_RING_TONE_TYPE, std::to_string(info.first));
226 int32_t changedRows = 0;
227 int32_t result = store.Update(changedRows, values, absRdbPredicates);
228 if (result != E_OK || changedRows <= 0) {
229 RINGTONE_ERR_LOG("Update operation failed. Result %{public}d. Updated %{public}d", result, changedRows);
230 }
231 }
232 }
233
AddVibrateTable(NativeRdb::RdbStore & store)234 static void AddVibrateTable(NativeRdb::RdbStore &store)
235 {
236 const vector<string> sqls = {
237 CREATE_VIBRATE_TABLE,
238 CREATE_SIMCARD_SETTING_TABLE,
239 INIT_SIMCARD_SETTING_TABLE,
240 };
241 int32_t errCode;
242 shared_ptr<NativePreferences::Preferences> prefs =
243 NativePreferences::PreferencesHelper::GetPreferences(COMMON_XML_EL1, errCode);
244 if (!prefs) {
245 RINGTONE_ERR_LOG("AddVibrateTable: update faild errCode=%{public}d", errCode);
246 } else {
247 prefs->PutInt(RINGTONE_PARAMETER_SCANNER_COMPLETED_KEY, RINGTONE_PARAMETER_SCANNER_COMPLETED_FALSE);
248 prefs->FlushSync();
249 }
250
251 RINGTONE_INFO_LOG("Add vibrate table");
252 ExecSqls(sqls, store);
253 }
254
UpgradeExtension(NativeRdb::RdbStore & store,int32_t oldVersion)255 static void UpgradeExtension(NativeRdb::RdbStore &store, int32_t oldVersion)
256 {
257 if (oldVersion < VERSION_ADD_DISPLAY_LANGUAGE_COLUMN) {
258 AddDisplayLanguageColumn(store);
259 }
260 if (oldVersion < VERSION_UPDATE_MIME_TYPE) {
261 UpdateMimeType(store);
262 }
263 if (oldVersion < VERSION_ADD_PRELOAD_CONF_TABLE) {
264 AddPreloadConfTable(store);
265 UpdateDefaultSystemTone(store);
266 }
267 if (oldVersion < VERSION_ADD_VIBRATE_TABLE) {
268 AddVibrateTable(store);
269 }
270 }
271
OnUpgrade(NativeRdb::RdbStore & store,int32_t oldVersion,int32_t newVersion)272 int32_t RingtoneDataCallBack::OnUpgrade(NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion)
273 {
274 RINGTONE_INFO_LOG("OnUpgrade old:%d, new:%d", oldVersion, newVersion);
275 UpgradeExtension(store, oldVersion);
276 return NativeRdb::E_OK;
277 }
278 } // namespace Media
279 } // namespace OHOS
280