• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "medialibrary_file_operations.h"
17 #include "media_log.h"
18 #include "media_file_utils.h"
19 #include "medialibrary_smartalbum_map_db.h"
20 
21 using namespace std;
22 using namespace OHOS::NativeRdb;
23 
24 namespace OHOS {
25 namespace Media {
UpdateDateModifiedForAlbum(const shared_ptr<RdbStore> & rdbStore,const string & albumPath)26 void UpdateDateModifiedForAlbum(const shared_ptr<RdbStore> &rdbStore, const string &albumPath)
27 {
28     if (!albumPath.empty()) {
29         int32_t count(0);
30         vector<string> whereArgs = { albumPath };
31         ValuesBucket valuesBucket;
32         valuesBucket.PutLong(MEDIA_DATA_DB_DATE_MODIFIED,
33             MediaLibraryDataAbilityUtils::GetAlbumDateModified(albumPath));
34 
35         int32_t updateResult = rdbStore->Update(count, MEDIALIBRARY_TABLE, valuesBucket,
36                                                 MEDIA_DATA_DB_FILE_PATH + " = ?", whereArgs);
37         if (updateResult != E_OK) {
38             MEDIA_ERR_LOG("Update failed for album");
39         }
40     }
41 }
42 
HandleCreateAsset(const ValuesBucket & values,const shared_ptr<RdbStore> & rdbStore)43 int32_t MediaLibraryFileOperations::HandleCreateAsset(const ValuesBucket &values,
44                                                       const shared_ptr<RdbStore> &rdbStore)
45 {
46     string relativePath(""), path(""), displayName("");
47     int32_t errCode = DATA_ABILITY_FAIL;
48     int32_t mediaType = static_cast<int32_t>(MEDIA_TYPE_FILE);
49     FileAsset fileAsset;
50     MediaLibraryFileDb fileDbOprn;
51     ValueObject valueObject;
52     NativeAlbumAsset  nativeAlbumAsset;
53     // Obtain file displayName
54     if (values.GetObject(MEDIA_DATA_DB_NAME, valueObject)) {
55         valueObject.GetString(displayName);
56     }
57 
58     // Obtain relative path
59     if (values.GetObject(MEDIA_DATA_DB_RELATIVE_PATH, valueObject)) {
60         valueObject.GetString(relativePath);
61         path = ROOT_MEDIA_DIR + relativePath + displayName;
62     }
63 
64     // Obtain mediatype
65     if (values.GetObject(MEDIA_DATA_DB_MEDIA_TYPE, valueObject)) {
66         valueObject.GetInt(mediaType);
67         fileAsset.SetMediaType(static_cast<MediaType>(mediaType));
68     }
69 
70     vector<int32_t> outIds;
71     nativeAlbumAsset = MediaLibraryDataAbilityUtils::CreateDirectorys(relativePath, rdbStore, outIds);
72     if (nativeAlbumAsset.GetAlbumId() < 0) {
73         return nativeAlbumAsset.GetAlbumId();
74     }
75     nativeAlbumAsset = MediaLibraryDataAbilityUtils::GetAlbumAsset(to_string(nativeAlbumAsset.GetAlbumId()), rdbStore);
76     if (MediaLibraryDataAbilityUtils::isFileExistInDb(path, rdbStore)) {
77         if (fileAsset.IsFileExists(path)) {
78             return DATA_ABILITY_DUPLICATE_CREATE;
79         } else {
80             int32_t deletedRows(FILE_OPERATION_ERR);
81             vector<string> whereArgs = { path };
82             int32_t deleteResult = rdbStore->Delete(deletedRows, MEDIALIBRARY_TABLE, "data = ?", whereArgs);
83             if (deleteResult != E_OK) {
84                 return errCode;
85             }
86         }
87     }
88     errCode = fileAsset.CreateAsset(path);
89     if (errCode == DATA_ABILITY_SUCCESS) {
90         // Fill basic file information into DB
91         ValuesBucket updatedAssetInfo = UpdateBasicAssetDetails(mediaType, displayName, relativePath, path);
92         updatedAssetInfo.PutInt(MEDIA_DATA_DB_BUCKET_ID, nativeAlbumAsset.GetAlbumId());
93         updatedAssetInfo.PutInt(MEDIA_DATA_DB_PARENT_ID, nativeAlbumAsset.GetAlbumId());
94         updatedAssetInfo.PutString(MEDIA_DATA_DB_BUCKET_NAME, nativeAlbumAsset.GetAlbumName());
95         // will return row id
96         return fileDbOprn.Insert(updatedAssetInfo, rdbStore);
97     }
98     return errCode;
99 }
100 
HandleCloseAsset(string & uriStr,string & srcPath,const ValuesBucket & values,const shared_ptr<RdbStore> & rdbStore)101 int32_t MediaLibraryFileOperations::HandleCloseAsset(string &uriStr, string &srcPath, const ValuesBucket &values,
102     const shared_ptr<RdbStore> &rdbStore)
103 {
104     int32_t errorCode = MediaLibraryDataAbilityUtils::setFilePending(uriStr, false, rdbStore);
105     if (errorCode == DATA_ABILITY_FAIL) {
106         MEDIA_ERR_LOG("HandleCloseAsset Set file to pending DB error");
107         return DATA_ABILITY_FAIL;
108     }
109 
110     string fileName;
111 
112     if (!srcPath.empty() && ((fileName = MediaLibraryDataAbilityUtils::GetFileName(srcPath)).length() != 0) &&
113         (fileName.at(0) != '.')) {
114         string albumPath = MediaLibraryDataAbilityUtils::GetParentPath(srcPath);
115         UpdateDateModifiedForAlbum(rdbStore, albumPath);
116     }
117 
118     return DATA_ABILITY_SUCCESS;
119 }
120 
HandleGetAlbumCapacity(const ValuesBucket & values,const shared_ptr<RdbStore> & rdbStore)121 int32_t MediaLibraryFileOperations::HandleGetAlbumCapacity(const ValuesBucket &values,
122     const shared_ptr<RdbStore> &rdbStore)
123 {
124     MEDIA_INFO_LOG("HandleGetAlbumCapacity IN");
125     int32_t errorCode = DATA_ABILITY_FAIL;
126     unique_ptr<AbsSharedResultSet> resultSet = nullptr;
127     ValueObject valueObject;
128     bool isFavourite = false;
129     if (values.GetObject(MEDIA_DATA_DB_IS_FAV, valueObject)) {
130         valueObject.GetBool(isFavourite);
131     }
132 
133     bool isTrash = false;
134     if (values.GetObject(MEDIA_DATA_DB_IS_TRASH, valueObject)) {
135         valueObject.GetBool(isTrash);
136     }
137 
138     if (isFavourite) {
139         MEDIA_INFO_LOG("HandleGetAlbumCapacity isFavourite");
140         resultSet= MediaLibraryDataAbilityUtils::QueryFavFiles(rdbStore);
141     } else if (isTrash) {
142         MEDIA_INFO_LOG("HandleGetAlbumCapacity isTrash");
143         resultSet= MediaLibraryDataAbilityUtils::QueryTrashFiles(rdbStore);
144     }
145 
146     if (resultSet != nullptr) {
147         resultSet->GetRowCount(errorCode);
148         MEDIA_INFO_LOG("HandleGetAlbumCapacity GetRowCount %{public}d", errorCode);
149     }
150 
151     MEDIA_INFO_LOG("HandleGetAlbumCapacity OUT");
152     return errorCode;
153 }
ModifyDisName(const string & dstFileName,const string & destAlbumPath,const string & srcPath,const shared_ptr<RdbStore> & rdbStore)154 int ModifyDisName(const string &dstFileName,
155     const string &destAlbumPath, const string &srcPath, const shared_ptr<RdbStore> &rdbStore)
156 {
157     int32_t errCode = DATA_ABILITY_SUCCESS;
158     if (dstFileName == ".nomedia") {
159         int32_t deletedRows(ALBUM_OPERATION_ERR);
160         vector<string> whereArgs = {(destAlbumPath.back() != '/' ?
161             (destAlbumPath + "/%") : (destAlbumPath + "%")), destAlbumPath};
162 
163         int32_t deleteResult = rdbStore->Delete(deletedRows, MEDIALIBRARY_TABLE,
164             MEDIA_DATA_DB_FILE_PATH + " LIKE ? OR " + MEDIA_DATA_DB_FILE_PATH + " = ?", whereArgs);
165         if (deleteResult != E_OK) {
166             MEDIA_ERR_LOG("Delete rows for the hidden album failed");
167         }
168         whereArgs.clear();
169         whereArgs.push_back(srcPath);
170         deleteResult = rdbStore->Delete(deletedRows, MEDIALIBRARY_TABLE, MEDIA_DATA_DB_FILE_PATH + " = ?", whereArgs);
171         if (deleteResult != E_OK) {
172             MEDIA_ERR_LOG("Delete rows for the old path failed");
173         }
174         errCode = DATA_ABILITY_FAIL;
175     }
176 
177     if ((!dstFileName.empty()) && (dstFileName.at(0) == '.')) {
178         int32_t deletedRows(ALBUM_OPERATION_ERR);
179         vector<string> whereArgs = { srcPath };
180 
181         int32_t deleteResult = rdbStore->Delete(deletedRows, MEDIALIBRARY_TABLE,
182                                                 MEDIA_DATA_DB_FILE_PATH + " = ?", whereArgs);
183         if (deleteResult != E_OK) {
184             MEDIA_ERR_LOG("Delete rows failed");
185         }
186         errCode = DATA_ABILITY_FAIL;
187     }
188     return errCode;
189 }
HandleModifyAsset(const string & rowNum,const string & srcPath,const ValuesBucket & values,const shared_ptr<RdbStore> & rdbStore)190 int32_t MediaLibraryFileOperations::HandleModifyAsset(const string &rowNum, const string &srcPath,
191     const ValuesBucket &values, const shared_ptr<RdbStore> &rdbStore)
192 {
193     string dstFilePath, dstReFilePath, dstFileName, destAlbumPath, bucketName;
194     int32_t errCode = DATA_ABILITY_SUCCESS;
195     int32_t bucketId = 0;
196     ValueObject valueObject;
197     FileAsset fileAsset;
198     MediaLibraryFileDb fileDbOprn;
199     if (values.GetObject(MEDIA_DATA_DB_NAME, valueObject)) {
200         valueObject.GetString(dstFileName);
201     }
202     if (values.GetObject(MEDIA_DATA_DB_RELATIVE_PATH, valueObject)) {
203         valueObject.GetString(dstReFilePath);
204     }
205     dstFilePath = ROOT_MEDIA_DIR + dstReFilePath + dstFileName;
206     destAlbumPath = ROOT_MEDIA_DIR + dstReFilePath;
207     if (destAlbumPath.back() == '/') {
208         destAlbumPath = destAlbumPath.substr(0, destAlbumPath.length() - 1);
209     }
210     MEDIA_ERR_LOG("HandleModifyAsset destAlbumPath = %{public}s", destAlbumPath.c_str());
211     bucketId = MediaLibraryDataAbilityUtils::GetParentIdFromDb(destAlbumPath, rdbStore);
212     if ((!dstReFilePath.empty()) && (bucketId == 0)) {
213         vector<int32_t> outIds;
214         NativeAlbumAsset nativeAlbumAsset = MediaLibraryDataAbilityUtils::CreateDirectorys(dstReFilePath,
215                                                                                            rdbStore, outIds);
216         if (nativeAlbumAsset.GetAlbumId() < 0) {
217             MEDIA_ERR_LOG("Failed to CreateDirectorys err:%{public}d", nativeAlbumAsset.GetAlbumId());
218             return nativeAlbumAsset.GetAlbumId();
219         }
220         bucketId = nativeAlbumAsset.GetAlbumId();
221     }
222 
223     bucketName = MediaLibraryDataAbilityUtils::GetParentDisplayNameFromDb(bucketId, rdbStore);
224     MEDIA_ERR_LOG("HandleModifyAsset bucketId = %{public}d bucketName = %{public}s", bucketId, bucketName.c_str());
225     if (srcPath.compare(dstFilePath) != 0) {
226         errCode = fileAsset.ModifyAsset(srcPath, dstFilePath);
227         if (errCode == DATA_ABILITY_MODIFY_DATA_FAIL) {
228             MEDIA_ERR_LOG("Failed to modify the file in the device");
229             return errCode;
230         }
231         errCode = ModifyDisName(dstFileName, destAlbumPath, srcPath, rdbStore);
232         if (errCode == DATA_ABILITY_FAIL) {
233             return errCode;
234         }
235         if (fileDbOprn.Modify(rowNum, dstFilePath, bucketId, bucketName, rdbStore) > 0) {
236             UpdateDateModifiedForAlbum(rdbStore, destAlbumPath);
237             string srcAlbumPath = MediaLibraryDataAbilityUtils::GetParentPath(srcPath);
238             UpdateDateModifiedForAlbum(rdbStore, srcAlbumPath);
239         }
240     }
241     return errCode;
242 }
243 
HandleDeleteAsset(const string & rowNum,const string & srcPath,const shared_ptr<RdbStore> & rdbStore)244 int32_t MediaLibraryFileOperations::HandleDeleteAsset(const string &rowNum, const string &srcPath,
245     const shared_ptr<RdbStore> &rdbStore)
246 {
247     int32_t errCode = DATA_ABILITY_FAIL;
248     FileAsset fileAsset;
249     MediaLibraryFileDb fileDbOprn;
250     MediaLibrarySmartAlbumMapDb smartAlbumMapDbOprn;
251     if (!srcPath.empty()) {
252         errCode = fileAsset.DeleteAsset(srcPath);
253     }
254 
255     if (errCode == DATA_ABILITY_SUCCESS) {
256         errCode = fileDbOprn.Delete(rowNum, rdbStore);
257         if (errCode > 0) {
258             string albumPath = MediaLibraryDataAbilityUtils::GetParentPath(srcPath);
259             UpdateDateModifiedForAlbum(rdbStore, albumPath);
260             smartAlbumMapDbOprn.DeleteAllAssetsMapInfo(std::stoi(rowNum), rdbStore);
261         }
262     }
263 
264     return errCode;
265 }
CreateThumbnail(const shared_ptr<RdbStore> & rdbStore,const shared_ptr<MediaLibraryThumbnail> & mediaThumbnail,string id)266 void CreateThumbnail(const shared_ptr<RdbStore> &rdbStore,
267     const shared_ptr<MediaLibraryThumbnail> &mediaThumbnail, string id)
268 {
269     if (!id.empty()) {
270         string kvId;
271         ThumbRdbOpt opts = {
272             .store = rdbStore,
273             .table = MEDIALIBRARY_TABLE,
274             .row = id
275         };
276 
277         if (!mediaThumbnail->CreateThumbnail(opts, kvId)) {
278             MEDIA_ERR_LOG("Create thumbnail error");
279         }
280     }
281 }
HandleIsDirectoryAsset(const ValuesBucket & values,const shared_ptr<RdbStore> & rdbStore)282 int32_t MediaLibraryFileOperations::HandleIsDirectoryAsset(const ValuesBucket &values,
283                                                            const shared_ptr<RdbStore> &rdbStore)
284 {
285     int32_t errCode = DATA_ABILITY_FAIL;
286     ValueObject valueObject;
287     int32_t id = 0;
288     unique_ptr<AbsSharedResultSet> queryResultSet;
289     std::vector<std::string> columns;
290     int32_t columnIndex;
291     string path = "";
292     columns.push_back(MEDIA_DATA_DB_FILE_PATH);
293     if (values.GetObject(MEDIA_DATA_DB_ID, valueObject)) {
294         valueObject.GetInt(id);
295     }
296     MEDIA_ERR_LOG("HandleIsDirectoryAsset id = %{public}d", id);
297     if (id != 0) {
298         AbsRdbPredicates mediaLibAbsPredFile(MEDIALIBRARY_TABLE);
299         mediaLibAbsPredFile.EqualTo(MEDIA_DATA_DB_ID, std::to_string(id));
300         queryResultSet = rdbStore->Query(mediaLibAbsPredFile, columns);
301         while (queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
302             queryResultSet->GetColumnIndex(MEDIA_DATA_DB_FILE_PATH, columnIndex);
303             queryResultSet->GetString(columnIndex, path);
304             MEDIA_ERR_LOG("HandleIsDirectoryAsset path = %{public}s", path.c_str());
305         }
306         if (MediaFileUtils::IsDirectory(path)) {
307             errCode = SUCCESS;
308         }
309     }
310     return errCode;
311 }
HandleFileOperation(const string & oprn,const ValuesBucket & values,const shared_ptr<RdbStore> & rdbStore,const std::shared_ptr<MediaLibraryThumbnail> & mediaThumbnail)312 int32_t MediaLibraryFileOperations::HandleFileOperation(const string &oprn, const ValuesBucket &values,
313     const shared_ptr<RdbStore> &rdbStore, const std::shared_ptr<MediaLibraryThumbnail> &mediaThumbnail)
314 {
315     int32_t errCode = DATA_ABILITY_FAIL;
316 
317     if (oprn == MEDIA_FILEOPRN_CREATEASSET) {
318         return HandleCreateAsset(values, rdbStore);
319     } else if (oprn == MEDIA_FILEOPRN_ISDIRECTORY) {
320         return HandleIsDirectoryAsset(values, rdbStore);
321     } else if (oprn == MEDIA_FILEOPRN_GETALBUMCAPACITY) {
322         return HandleGetAlbumCapacity(values, rdbStore);
323     }
324 
325     string actualUri;
326     ValueObject valueObject;
327 
328     if (values.GetObject(MEDIA_DATA_DB_URI, valueObject)) {
329         valueObject.GetString(actualUri);
330     }
331     string srcPath;
332     string networkId = MediaLibraryDataAbilityUtils::GetNetworkIdFromUri(actualUri);
333     if (!networkId.empty()) {
334         if (oprn == MEDIA_FILEOPRN_CLOSEASSET) {
335             return HandleCloseAsset(actualUri, srcPath, values, rdbStore);
336         } else {
337             return errCode;
338         }
339     }
340 
341     string id = MediaLibraryDataAbilityUtils::GetIdFromUri(actualUri);
342     srcPath = MediaLibraryDataAbilityUtils::GetPathFromDb(id, rdbStore);
343     CHECK_AND_RETURN_RET_LOG(!srcPath.empty(), DATA_ABILITY_FAIL, "Failed to obtain path from Database");
344 
345     if (oprn == MEDIA_FILEOPRN_MODIFYASSET) {
346         errCode = HandleModifyAsset(id, srcPath, values, rdbStore);
347     } else if (oprn == MEDIA_FILEOPRN_DELETEASSET) {
348         errCode = HandleDeleteAsset(id, srcPath, rdbStore);
349     } else if (oprn == MEDIA_FILEOPRN_CLOSEASSET) {
350         errCode = HandleCloseAsset(actualUri, srcPath, values, rdbStore);
351     }
352     if (oprn == MEDIA_FILEOPRN_CLOSEASSET) {
353         CreateThumbnail(rdbStore, mediaThumbnail, id);
354     }
355 
356     return errCode;
357 }
358 
UpdateBasicAssetDetails(int32_t mediaType,const string & fileName,const string & relPath,const string & path)359 ValuesBucket MediaLibraryFileOperations::UpdateBasicAssetDetails(int32_t mediaType,
360                                                                  const string &fileName,
361                                                                  const string &relPath,
362                                                                  const string &path)
363 {
364     ValuesBucket assetInfoBucket;
365     assetInfoBucket.PutString(Media::MEDIA_DATA_DB_RELATIVE_PATH, relPath);
366     assetInfoBucket.PutString(Media::MEDIA_DATA_DB_NAME, fileName);
367     assetInfoBucket.PutString(Media::MEDIA_DATA_DB_TITLE, MediaLibraryDataAbilityUtils::GetFileTitle(fileName));
368     struct stat statInfo {};
369     if (stat(path.c_str(), &statInfo) == 0) {
370         assetInfoBucket.PutLong(Media::MEDIA_DATA_DB_SIZE, statInfo.st_size);
371         assetInfoBucket.PutLong(Media::MEDIA_DATA_DB_DATE_ADDED, statInfo.st_ctime);
372     }
373     assetInfoBucket.PutInt(Media::MEDIA_DATA_DB_MEDIA_TYPE, mediaType);
374     assetInfoBucket.PutString(Media::MEDIA_DATA_DB_FILE_PATH, path);
375     return assetInfoBucket;
376 }
377 } // namespace Media
378 } // namespace OHOS
379