• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define MLOG_TAG "RingtoneRestore"
17 
18 #include "ringtone_restore.h"
19 
20 #include <sys/stat.h>
21 
22 #include "datashare_ext_ability.h"
23 #include "datashare_ext_ability_context.h"
24 #include "result_set_utils.h"
25 #include "ringtone_restore_type.h"
26 #include "ringtone_restore_db_utils.h"
27 #include "ringtone_errno.h"
28 #include "ringtone_file_utils.h"
29 #include "ringtone_log.h"
30 #include "ringtone_type.h"
31 
32 namespace OHOS {
33 namespace Media {
34 using namespace std;
35 static const int32_t QUERY_COUNT = 500;
36 static const int32_t INVALID_QUERY_OFFSET = -1;
Init(const std::string & backupPath)37 int32_t RingtoneRestore::Init(const std::string &backupPath)
38 {
39     RINGTONE_INFO_LOG("Init db start");
40     if (backupPath.empty()) {
41         RINGTONE_ERR_LOG("error: backup path is null");
42         return E_INVALID_ARGUMENTS;
43     }
44     dbPath_ = backupPath + RINGTONE_LIBRARY_DB_PATH_EL1 + "/rdb" + "/" + RINGTONE_LIBRARY_DB_NAME;
45     if (!RingtoneFileUtils::IsFileExists(dbPath_)) {
46         RINGTONE_ERR_LOG("ringtone db is not exist, path=%{public}s", dbPath_.c_str());
47         dbPath_ = backupPath + RINGTONE_LIBRARY_DB_PATH + "/rdb" + "/" + RINGTONE_LIBRARY_DB_NAME;
48         if (!RingtoneFileUtils::IsFileExists(dbPath_)) {
49             RINGTONE_ERR_LOG("ringtone db is not exist, path=%{public}s", dbPath_.c_str());
50             return E_FAIL;
51         }
52     }
53     backupPath_ = backupPath;
54     int32_t err = RingtoneRestoreDbUtils::InitDb(restoreRdb_, RINGTONE_LIBRARY_DB_NAME, dbPath_,
55         RINGTONE_BUNDLE_NAME, true);
56     if (err != E_OK) {
57         RINGTONE_ERR_LOG("ringtone rdb fail, err = %{public}d", err);
58         return E_HAS_DB_ERROR;
59     }
60     if (RingtoneRestoreBase::Init(backupPath) != E_OK) {
61         return E_FAIL;
62     }
63 
64     RINGTONE_INFO_LOG("Init db successfully");
65     return E_OK;
66 }
67 
QueryFileInfos(int32_t offset)68 vector<FileInfo> RingtoneRestore::QueryFileInfos(int32_t offset)
69 {
70     vector<FileInfo> result;
71     string querySql = "SELECT * FROM " + RINGTONE_TABLE;
72     if (offset != INVALID_QUERY_OFFSET) {
73         querySql += " LIMIT " + to_string(offset) + ", " + to_string(QUERY_COUNT);
74     }
75     auto resultSet = restoreRdb_->QuerySql(querySql);
76     if (resultSet == nullptr) {
77         return {};
78     }
79 
80     vector<shared_ptr<RingtoneMetadata>> metaDatas {};
81     auto ret = resultSet->GoToFirstRow();
82     while (ret == NativeRdb::E_OK) {
83         auto metaData = make_unique<RingtoneMetadata>();
84         if (PopulateMetadata(resultSet, metaData) != E_OK) {
85             RINGTONE_INFO_LOG("read resultset error");
86             continue;
87         }
88         metaDatas.push_back(std::move(metaData));
89         ret = resultSet->GoToNextRow();
90     };
91     resultSet->Close();
92 
93     return ConvertToFileInfos(metaDatas);
94 }
95 
ConvertToFileInfos(vector<shared_ptr<RingtoneMetadata>> & metaDatas)96 vector<FileInfo> RingtoneRestore::ConvertToFileInfos(vector<shared_ptr<RingtoneMetadata>> &metaDatas)
97 {
98     vector<FileInfo> infos = {};
99     for (auto meta : metaDatas) {
100         infos.emplace_back(*meta);
101     }
102     return infos;
103 }
104 
CheckRestoreFileInfos(vector<FileInfo> & infos)105 void RingtoneRestore::CheckRestoreFileInfos(vector<FileInfo> &infos)
106 {
107     for (auto it = infos.begin(); it != infos.end();) {
108         // at first, check backup file path
109         string srcPath = backupPath_ + it->data;
110         if (!RingtoneFileUtils::IsFileExists(srcPath)) {
111             // 系统铃音不克隆,需要进行设置铃音判断
112             if (it->sourceType == SOURCE_TYPE_PRESET) {
113                 it->restorePath = it->data;
114                 CheckSetting(*it);
115             }
116             RINGTONE_INFO_LOG("warnning:backup file is not exist, path=%{private}s", srcPath.c_str());
117             infos.erase(it);
118         } else {
119             it++;
120         }
121     }
122 }
123 
StartRestore()124 int32_t RingtoneRestore::StartRestore()
125 {
126     if (restoreRdb_ == nullptr || backupPath_.empty()) {
127         return E_FAIL;
128     }
129     auto ret = RingtoneRestoreBase::StartRestore();
130     if (ret != E_OK) {
131         return ret;
132     }
133     CheckNotRingtoneRestore();
134     auto infos = QueryFileInfos(INVALID_QUERY_OFFSET);
135     if ((!infos.empty()) && (infos.size() != 0)) {
136         CheckRestoreFileInfos(infos);
137         ret = InsertTones(infos);
138     }
139     FlushSettings();
140     return ret;
141 }
142 
UpdateRestoreFileInfo(FileInfo & info)143 void RingtoneRestore::UpdateRestoreFileInfo(FileInfo &info)
144 {
145     info.displayName = RingtoneFileUtils::GetFileNameFromPath(info.restorePath);
146     if (info.title == TITLE_DEFAULT) {
147         info.title = RingtoneFileUtils::GetBaseNameFromPath(info.restorePath);
148     }
149 
150     struct stat statInfo;
151     if (stat(info.restorePath.c_str(), &statInfo) != 0) {
152         RINGTONE_ERR_LOG("stat syscall err %{public}d", errno);
153         return;
154     }
155     info.dateModified = static_cast<int64_t>(RingtoneFileUtils::Timespec2Millisecond(statInfo.st_mtim));
156 }
157 
OnPrepare(FileInfo & info,const std::string & destPath)158 bool RingtoneRestore::OnPrepare(FileInfo &info, const std::string &destPath)
159 {
160     if (!RingtoneFileUtils::IsFileExists(destPath)) {
161         return false;
162     }
163 
164     string fileName = RingtoneFileUtils::GetFileNameFromPath(info.data);
165     if (fileName.empty()) {
166         RINGTONE_ERR_LOG("src file name is null");
167         return false;
168     }
169     string baseName = RingtoneFileUtils::GetBaseNameFromPath(info.data);
170     if (baseName.empty()) {
171         RINGTONE_ERR_LOG("src file base name is null");
172         return false;
173     }
174     string extensionName = RingtoneFileUtils::GetExtensionFromPath(info.data);
175 
176     int32_t repeatCount = 1;
177     string srcPath = backupPath_ + info.data;
178     info.restorePath = destPath + "/" + fileName;
179     while (RingtoneFileUtils::IsFileExists(info.restorePath)) {
180         if (RingtoneFileUtils::IsSameFile(srcPath, info.restorePath)) {
181             CheckSetting(info);
182             RINGTONE_ERR_LOG("samefile: srcPath=%{private}s, dstPath=%{private}s", srcPath.c_str(),
183                 info.restorePath.c_str());
184             return false;
185         }
186         info.restorePath = destPath + "/" + baseName + "(" + to_string(repeatCount++) + ")" + "." + extensionName;
187     }
188 
189     if (!RingtoneRestoreBase::MoveFile(srcPath, info.restorePath)) {
190         return false;
191     }
192 
193     UpdateRestoreFileInfo(info);
194 
195     return true;
196 }
197 
OnFinished(vector<FileInfo> & infos)198 void RingtoneRestore::OnFinished(vector<FileInfo> &infos)
199 {
200     if (!RingtoneFileUtils::RemoveDirectory(backupPath_)) {
201         RINGTONE_ERR_LOG("cleanup backup dir failed, restorepath=%{public}s, err: %{public}s",
202             backupPath_.c_str(), strerror(errno));
203     }
204 }
205 
CheckNotRingtoneRestore()206 void RingtoneRestore::CheckNotRingtoneRestore()
207 {
208     // SIM_CARD_1 ring no ringtone
209     if (RingtoneRestoreBase::DetermineNoRingtone(RINGTONE_COLUMN_RING_TONE_TYPE,
210         RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE, RING_TONE_TYPE_SIM_CARD_1, RING_TONE_TYPE_SIM_CARD_BOTH, restoreRdb_) &&
211         RingtoneRestoreBase::NeedCommitSetting(RINGTONE_COLUMN_RING_TONE_TYPE,
212             RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE, RING_TONE_TYPE_SIM_CARD_1, RING_TONE_TYPE_SIM_CARD_BOTH)) {
213         RINGTONE_INFO_LOG("no ringtone sound for ringtone sim card 1");
214         RingtoneRestoreBase::SetNotRingtone(RINGTONE_COLUMN_RING_TONE_TYPE,
215             RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE, SIM_CARD_1);
216     }
217     // SIM_CARD_2 ring no ringtone
218     if (RingtoneRestoreBase::DetermineNoRingtone(RINGTONE_COLUMN_RING_TONE_TYPE,
219         RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE, RING_TONE_TYPE_SIM_CARD_2, RING_TONE_TYPE_SIM_CARD_BOTH, restoreRdb_) &&
220         RingtoneRestoreBase::NeedCommitSetting(RINGTONE_COLUMN_RING_TONE_TYPE,
221             RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE, RING_TONE_TYPE_SIM_CARD_2, RING_TONE_TYPE_SIM_CARD_BOTH)) {
222         RINGTONE_INFO_LOG("no ringtone sound for ringtone sim card 2");
223         RingtoneRestoreBase::SetNotRingtone(RINGTONE_COLUMN_RING_TONE_TYPE,
224             RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE, SIM_CARD_2);
225     }
226     // SIM_CARD_1 shot no ringtone
227     if (RingtoneRestoreBase::DetermineNoRingtone(RINGTONE_COLUMN_SHOT_TONE_TYPE,
228         RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, SHOT_TONE_TYPE_SIM_CARD_1, SHOT_TONE_TYPE_SIM_CARD_BOTH, restoreRdb_) &&
229         RingtoneRestoreBase::NeedCommitSetting(RINGTONE_COLUMN_SHOT_TONE_TYPE,
230             RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, SHOT_TONE_TYPE_SIM_CARD_1, SHOT_TONE_TYPE_SIM_CARD_BOTH)) {
231         RINGTONE_INFO_LOG("no shot sound for shot sim card 1");
232         RingtoneRestoreBase::SetNotRingtone(RINGTONE_COLUMN_SHOT_TONE_TYPE,
233             RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, SIM_CARD_1);
234     }
235     // SIM_CARD_2 shot no ringtone
236     if (RingtoneRestoreBase::DetermineNoRingtone(RINGTONE_COLUMN_SHOT_TONE_TYPE,
237         RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, SHOT_TONE_TYPE_SIM_CARD_2, SHOT_TONE_TYPE_SIM_CARD_BOTH, restoreRdb_) &&
238         RingtoneRestoreBase::NeedCommitSetting(RINGTONE_COLUMN_SHOT_TONE_TYPE,
239             RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, SHOT_TONE_TYPE_SIM_CARD_2, SHOT_TONE_TYPE_SIM_CARD_BOTH)) {
240         RINGTONE_INFO_LOG("no shot sound for shot sim card 2");
241         RingtoneRestoreBase::SetNotRingtone(RINGTONE_COLUMN_SHOT_TONE_TYPE,
242             RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, SIM_CARD_2);
243     }
244     // notification
245     if (RingtoneRestoreBase::DetermineNoRingtone(RINGTONE_COLUMN_NOTIFICATION_TONE_TYPE,
246         RINGTONE_COLUMN_NOTIFICATION_TONE_SOURCE_TYPE, NOTIFICATION_TONE_TYPE, NOTIFICATION_TONE_TYPE, restoreRdb_) &&
247         RingtoneRestoreBase::NeedCommitSetting(RINGTONE_COLUMN_NOTIFICATION_TONE_TYPE,
248             RINGTONE_COLUMN_NOTIFICATION_TONE_SOURCE_TYPE, NOTIFICATION_TONE_TYPE, NOTIFICATION_TONE_TYPE)) {
249         RINGTONE_INFO_LOG("no notification sound for notification");
250         RingtoneRestoreBase::SetNotRingtone(RINGTONE_COLUMN_NOTIFICATION_TONE_TYPE,
251             RINGTONE_COLUMN_NOTIFICATION_TONE_SOURCE_TYPE, SIM_CARD_1);
252     }
253 }
254 } // namespace Media
255 } // namespace OHOS
256