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
29 namespace OHOS {
30 namespace Media {
31 using namespace std;
32
33 const string DEFAULT_MIME_TYPE = "application/octet-stream";
34
35 const std::string CREATE_RINGTONE_TABLE = "CREATE TABLE IF NOT EXISTS " + RINGTONE_TABLE + "(" +
36 RINGTONE_COLUMN_TONE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
37 RINGTONE_COLUMN_DATA + " TEXT , " +
38 RINGTONE_COLUMN_SIZE + " BIGINT DEFAULT 0, " +
39 RINGTONE_COLUMN_DISPLAY_NAME + " TEXT , " +
40 RINGTONE_COLUMN_TITLE + " TEXT , " +
41 RINGTONE_COLUMN_MEDIA_TYPE + " INT DEFAULT 0, " +
42 RINGTONE_COLUMN_TONE_TYPE + " INT DEFAULT 0, " +
43 RINGTONE_COLUMN_MIME_TYPE + " TEXT , " +
44 RINGTONE_COLUMN_SOURCE_TYPE + " INT DEFAULT 0, " +
45 RINGTONE_COLUMN_DATE_ADDED + " BIGINT DEFAULT 0, " +
46 RINGTONE_COLUMN_DATE_MODIFIED + " BIGINT DEFAULT 0, " +
47 RINGTONE_COLUMN_DATE_TAKEN + " BIGINT DEFAULT 0, " +
48 RINGTONE_COLUMN_DURATION + " INT DEFAULT 0, " +
49 RINGTONE_COLUMN_SHOT_TONE_TYPE + " INT DEFAULT 0, " +
50 RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE + " INT DEFAULT 0, " +
51 RINGTONE_COLUMN_NOTIFICATION_TONE_TYPE + " INT DEFAULT 0, " +
52 RINGTONE_COLUMN_NOTIFICATION_TONE_SOURCE_TYPE + " INT DEFAULT 0, " +
53 RINGTONE_COLUMN_RING_TONE_TYPE + " INT DEFAULT 0, " +
54 RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE + " INT DEFAULT 0, " +
55 RINGTONE_COLUMN_ALARM_TONE_TYPE + " INT DEFAULT 0, " +
56 RINGTONE_COLUMN_ALARM_TONE_SOURCE_TYPE + " INT DEFAULT 0, " +
57 RINGTONE_COLUMN_DISPLAY_LANGUAGE_TYPE + " TEXT " + ")";
58
59 const std::string CREATE_PRELOAD_CONF_TABLE = "CREATE TABLE IF NOT EXISTS " + PRELOAD_CONFIG_TABLE + "(" +
60 PRELOAD_CONFIG_COLUMN_RING_TONE_TYPE + " INTEGER PRIMARY KEY," +
61 PRELOAD_CONFIG_COLUMN_TONE_ID + " INTEGER ," +
62 PRELOAD_CONFIG_COLUMN_DISPLAY_NAME + " TEXT " + ")";
63
64 const std::string INIT_PRELOAD_CONF_TABLE = "INSERT OR IGNORE INTO " + PRELOAD_CONFIG_TABLE + " (" +
65 PRELOAD_CONFIG_COLUMN_RING_TONE_TYPE + ") VALUES (1), (2), (3), (4), (5), (6);";
66
67 static const vector<string> g_initSqls = {
68 CREATE_RINGTONE_TABLE,
69 CREATE_PRELOAD_CONF_TABLE,
70 INIT_PRELOAD_CONF_TABLE,
71 };
72
RingtoneDataCallBack(void)73 RingtoneDataCallBack::RingtoneDataCallBack(void)
74 {
75 }
76
~RingtoneDataCallBack(void)77 RingtoneDataCallBack::~RingtoneDataCallBack(void)
78 {
79 }
80
InitSql(NativeRdb::RdbStore & store)81 int32_t RingtoneDataCallBack::InitSql(NativeRdb::RdbStore &store)
82 {
83 for (const string &sqlStr : g_initSqls) {
84 if (store.ExecuteSql(sqlStr) != NativeRdb::E_OK) {
85 RINGTONE_ERR_LOG("Failed to execute sql");
86 return NativeRdb::E_ERROR;
87 }
88 }
89 return NativeRdb::E_OK;
90 }
91
OnCreate(NativeRdb::RdbStore & store)92 int32_t RingtoneDataCallBack::OnCreate(NativeRdb::RdbStore &store)
93 {
94 if (InitSql(store) != NativeRdb::E_OK) {
95 RINGTONE_DEBUG_LOG("Failed to init sql");
96 return NativeRdb::E_ERROR;
97 }
98
99 RingtoneFileUtils::CreateRingtoneDir();
100 return NativeRdb::E_OK;
101 }
102
ExecSqls(const vector<string> & sqls,NativeRdb::RdbStore & store)103 static void ExecSqls(const vector<string> &sqls, NativeRdb::RdbStore &store)
104 {
105 int32_t err = NativeRdb::E_OK;
106 for (const auto &sql : sqls) {
107 err = store.ExecuteSql(sql);
108 if (err != NativeRdb::E_OK) {
109 RINGTONE_ERR_LOG("Failed to exec: %{private}s", sql.c_str());
110 continue;
111 }
112 }
113 }
114
AddDisplayLanguageColumn(NativeRdb::RdbStore & store)115 static void AddDisplayLanguageColumn(NativeRdb::RdbStore &store)
116 {
117 const vector<string> sqls = {
118 "ALTER TABLE " + RINGTONE_TABLE + " ADD COLUMN " + RINGTONE_COLUMN_DISPLAY_LANGUAGE_TYPE + " TEXT",
119 };
120 RINGTONE_INFO_LOG("Add display language column");
121 ExecSqls(sqls, store);
122 }
123
UpdateMimeType(NativeRdb::RdbStore & store)124 static void UpdateMimeType(NativeRdb::RdbStore &store)
125 {
126 RINGTONE_INFO_LOG("Update MimeType Begin");
127 RingtoneMimeTypeUtils::InitMimeTypeMap();
128 const string sql = "SELECT * FROM " + RINGTONE_TABLE;
129 auto resultSet = store.QuerySql(sql);
130 if (resultSet == nullptr) {
131 RINGTONE_ERR_LOG("error query sql %{public}s", sql.c_str());
132 return;
133 }
134 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
135 std::string mimeType = GetStringVal(RINGTONE_COLUMN_MIME_TYPE, resultSet);
136 if (mimeType != DEFAULT_MIME_TYPE) {
137 continue;
138 }
139 string displayName = GetStringVal(RINGTONE_COLUMN_DISPLAY_NAME, resultSet);
140 int32_t toneid = GetInt32Val(RINGTONE_COLUMN_TONE_ID, resultSet);
141 std::string extension = RingtoneFileUtils::GetFileExtension(displayName);
142 mimeType = RingtoneMimeTypeUtils::GetMimeTypeFromExtension(extension);
143 int32_t mime = RingtoneMimeTypeUtils::GetMediaTypeFromMimeType(mimeType);
144 RINGTONE_INFO_LOG("extension: %{public}s, mimeType: %{public}s, toneid: %{public}d mime: %{public}d",
145 extension.c_str(), mimeType.c_str(), toneid, mime);
146
147 NativeRdb::ValuesBucket values;
148 values.PutString(RINGTONE_COLUMN_MIME_TYPE, mimeType);
149 values.PutInt(RINGTONE_COLUMN_MEDIA_TYPE, mime);
150 NativeRdb::AbsRdbPredicates absRdbPredicates(RINGTONE_TABLE);
151 absRdbPredicates.EqualTo(RINGTONE_COLUMN_TONE_ID, toneid);
152 int32_t changedRows;
153 int32_t result = store.Update(changedRows, values, absRdbPredicates);
154 if (result != E_OK || changedRows <= 0) {
155 RINGTONE_ERR_LOG("Update operation failed. Result %{public}d. Updated %{public}d", result, changedRows);
156 }
157 }
158 resultSet->Close();
159 }
160
AddPreloadConfTable(NativeRdb::RdbStore & store)161 static void AddPreloadConfTable(NativeRdb::RdbStore &store)
162 {
163 const vector<string> sqls = {
164 CREATE_PRELOAD_CONF_TABLE,
165 INIT_PRELOAD_CONF_TABLE
166 };
167 RINGTONE_INFO_LOG("Add preload config table");
168 ExecSqls(sqls, store);
169 }
170
UpdateDefaultSystemTone(NativeRdb::RdbStore & store)171 static void UpdateDefaultSystemTone(NativeRdb::RdbStore &store)
172 {
173 RINGTONE_INFO_LOG("setting system tone begin");
174 auto infos = RingtoneUtils::GetDefaultSystemtoneInfo();
175 for (auto info : infos) {
176 const string querySql = "SELECT tone_id FROM ToneFiles WHERE display_name = "s + "\"" + info.second + "\"";
177 auto resultSet = store.QuerySql(querySql);
178 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
179 RINGTONE_ERR_LOG("Update operation failed. no resultSet");
180 continue;
181 }
182
183 int32_t tone_id = GetInt32Val("tone_id", resultSet);
184 NativeRdb::ValuesBucket values;
185 values.PutString(PRELOAD_CONFIG_COLUMN_DISPLAY_NAME, info.second);
186 values.PutInt(PRELOAD_CONFIG_COLUMN_TONE_ID, tone_id);
187 NativeRdb::AbsRdbPredicates absRdbPredicates(PRELOAD_CONFIG_TABLE);
188 absRdbPredicates.EqualTo(PRELOAD_CONFIG_COLUMN_RING_TONE_TYPE, std::to_string(info.first));
189 int32_t changedRows = 0;
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 }
196
UpgradeExtension(NativeRdb::RdbStore & store,int32_t oldVersion)197 static void UpgradeExtension(NativeRdb::RdbStore &store, int32_t oldVersion)
198 {
199 if (oldVersion < VERSION_ADD_DISPLAY_LANGUAGE_COLUMN) {
200 AddDisplayLanguageColumn(store);
201 }
202 if (oldVersion < VERSION_UPDATE_MIME_TYPE) {
203 UpdateMimeType(store);
204 }
205 if (oldVersion < VERSION_ADD_PRELOAD_CONF_TABLE) {
206 AddPreloadConfTable(store);
207 UpdateDefaultSystemTone(store);
208 }
209 }
210
OnUpgrade(NativeRdb::RdbStore & store,int32_t oldVersion,int32_t newVersion)211 int32_t RingtoneDataCallBack::OnUpgrade(NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion)
212 {
213 RINGTONE_INFO_LOG("OnUpgrade old:%d, new:%d", oldVersion, newVersion);
214 UpgradeExtension(store, oldVersion);
215 return NativeRdb::E_OK;
216 }
217 } // namespace Media
218 } // namespace OHOS
219