• 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 #include "photo_album_impl.h"
17 
18 #include "media_column.h"
19 #include "media_file_utils.h"
20 #include "medialibrary_errno.h"
21 #include "userfile_client.h"
22 #include "userfile_manager_types.h"
23 
24 using namespace std;
25 using namespace OHOS::DataShare;
26 
27 namespace OHOS {
28 namespace Media {
PhotoAlbumImpl(std::unique_ptr<PhotoAlbum> photoAlbumPtr_)29 PhotoAlbumImpl::PhotoAlbumImpl(std::unique_ptr<PhotoAlbum> photoAlbumPtr_)
30 {
31     photoAlbumPtr = move(photoAlbumPtr_);
32 }
33 
PhotoAlbumImpl(std::shared_ptr<PhotoAlbum> photoAlbumPtr_)34 PhotoAlbumImpl::PhotoAlbumImpl(std::shared_ptr<PhotoAlbum> photoAlbumPtr_)
35 {
36     photoAlbumPtr = photoAlbumPtr_;
37 }
38 
GetPhotoAlbumInstance()39 shared_ptr<PhotoAlbum> PhotoAlbumImpl::GetPhotoAlbumInstance()
40 {
41     return photoAlbumPtr;
42 }
43 
GetPhotoAlbumType() const44 int32_t PhotoAlbumImpl::GetPhotoAlbumType() const
45 {
46     return static_cast<int32_t>(photoAlbumPtr->GetPhotoAlbumType());
47 }
48 
GetPhotoAlbumSubType() const49 int32_t PhotoAlbumImpl::GetPhotoAlbumSubType() const
50 {
51     return static_cast<int32_t>(photoAlbumPtr->GetPhotoAlbumSubType());
52 }
53 
GetAlbumName() const54 string PhotoAlbumImpl::GetAlbumName() const
55 {
56     return photoAlbumPtr->GetAlbumName();
57 }
58 
SetAlbumName(char * cAlbumName)59 void PhotoAlbumImpl::SetAlbumName(char* cAlbumName)
60 {
61     string albumName(cAlbumName);
62     photoAlbumPtr->SetAlbumName(albumName);
63 }
64 
GetAlbumUri() const65 string PhotoAlbumImpl::GetAlbumUri() const
66 {
67     return photoAlbumPtr->GetAlbumUri();
68 }
69 
GetCount() const70 int32_t PhotoAlbumImpl::GetCount() const
71 {
72     return photoAlbumPtr->GetCount();
73 }
74 
GetCoverUri() const75 string PhotoAlbumImpl::GetCoverUri() const
76 {
77     return photoAlbumPtr->GetCoverUri();
78 }
79 
GetImageCount() const80 int32_t PhotoAlbumImpl::GetImageCount() const
81 {
82     return photoAlbumPtr->GetImageCount();
83 }
84 
GetVideoCount() const85 int32_t PhotoAlbumImpl::GetVideoCount() const
86 {
87     return photoAlbumPtr->GetVideoCount();
88 }
89 
GetPredicatesByAlbumTypes(const shared_ptr<PhotoAlbum> & photoAlbum,DataSharePredicates & predicates,const bool hiddenOnly)90 static int32_t GetPredicatesByAlbumTypes(const shared_ptr<PhotoAlbum> &photoAlbum,
91     DataSharePredicates &predicates, const bool hiddenOnly)
92 {
93     auto albumId = photoAlbum->GetAlbumId();
94     auto subType = photoAlbum->GetPhotoAlbumSubType();
95     bool isLocationAlbum = subType == PhotoAlbumSubType::GEOGRAPHY_LOCATION;
96     if (albumId <= 0 && !isLocationAlbum) {
97         return E_INVALID_ARGUMENTS;
98     }
99     auto type = photoAlbum->GetPhotoAlbumType();
100     if ((!PhotoAlbum::CheckPhotoAlbumType(type)) || (!PhotoAlbum::CheckPhotoAlbumSubType(subType))) {
101         return E_INVALID_ARGUMENTS;
102     }
103 
104     if (type == PhotoAlbumType::SMART && subType == PhotoAlbumSubType::PORTRAIT) {
105         return MediaLibraryNapiUtils::GetPortraitAlbumPredicates(photoAlbum->GetAlbumId(), predicates);
106     }
107 
108     if (PhotoAlbum::IsUserPhotoAlbum(type, subType)) {
109         return MediaLibraryNapiUtils::GetUserAlbumPredicates(photoAlbum->GetAlbumId(), predicates, hiddenOnly);
110     }
111 
112     if (PhotoAlbum::IsSourceAlbum(type, subType)) {
113         return MediaLibraryNapiUtils::GetSourceAlbumPredicates(photoAlbum->GetAlbumId(), predicates, hiddenOnly);
114     }
115 
116     if (type == PhotoAlbumType::SMART) {
117         if (isLocationAlbum) {
118             return MediaLibraryNapiUtils::GetAllLocationPredicates(predicates);
119         }
120         auto albumName = photoAlbum->GetAlbumName();
121         if (MediaLibraryNapiUtils::IsFeaturedSinglePortraitAlbum(albumName, predicates)) {
122             return MediaLibraryNapiUtils::GetFeaturedSinglePortraitAlbumPredicates(
123                 photoAlbum->GetAlbumId(), predicates);
124         }
125         return MediaLibraryNapiUtils::GetAnalysisAlbumPredicates(photoAlbum->GetAlbumId(), predicates);
126     }
127 
128     if ((type != PhotoAlbumType::SYSTEM) || (subType == PhotoAlbumSubType::USER_GENERIC) ||
129         (subType == PhotoAlbumSubType::ANY)) {
130         return E_INVALID_ARGUMENTS;
131     }
132     return MediaLibraryNapiUtils::GetSystemAlbumPredicates(subType, predicates, hiddenOnly);
133 }
134 
ParseArgsGetPhotoAssets(COptions options,DataSharePredicates & predicates,vector<string> & fetchColumn,ExtraInfo & extraInfo,int32_t & errCode)135 void PhotoAlbumImpl::ParseArgsGetPhotoAssets(COptions options, DataSharePredicates &predicates,
136     vector<string> &fetchColumn, ExtraInfo &extraInfo, int32_t &errCode)
137 {
138     extraInfo.fetchOptType = ASSET_FETCH_OPT;
139     GetFetchOption(options, predicates, fetchColumn, extraInfo, errCode);
140     if (errCode != E_SUCCESS) {
141         LOGE("GetFetchOption failed.");
142         return;
143     }
144     auto ret = GetPredicatesByAlbumTypes(photoAlbumPtr, predicates, photoAlbumPtr->GetHiddenOnly());
145     if (ret != E_SUCCESS) {
146         LOGE("GetPredicatesByAlbumTypes failed.");
147         errCode = JS_ERR_PARAMETER_INVALID;
148         return;
149     }
150     AddDefaultAssetColumns(fetchColumn,
151         PhotoColumn::IsPhotoColumn, NapiAssetType::TYPE_PHOTO, errCode);
152     if (errCode != E_SUCCESS) {
153         LOGE("AddDefaultAssetColumns failed.");
154         return;
155     }
156     if (photoAlbumPtr->GetHiddenOnly() || photoAlbumPtr->GetPhotoAlbumSubType() == PhotoAlbumSubType::HIDDEN) {
157         if (!MediaLibraryNapiUtils::IsSystemApp()) {
158             LOGE("This interface can be called only by system apps");
159             errCode = E_CHECK_SYSTEMAPP_FAIL;
160             return;
161         }
162         // sort by hidden time desc if is hidden asset
163         predicates.IndexedBy(PhotoColumn::PHOTO_HIDDEN_TIME_INDEX);
164     }
165 }
166 
IsFeaturedSinglePortraitAlbum(const shared_ptr<PhotoAlbum> & photoAlbumPtr)167 static bool IsFeaturedSinglePortraitAlbum(const shared_ptr<PhotoAlbum>& photoAlbumPtr)
168 {
169     constexpr int portraitAlbumId = 0;
170     return photoAlbumPtr->GetPhotoAlbumSubType() == PhotoAlbumSubType::CLASSIFY &&
171         photoAlbumPtr->GetAlbumName().compare(to_string(portraitAlbumId)) == 0;
172 }
173 
ConvertColumnsForPortrait(const shared_ptr<PhotoAlbum> & photoAlbumPtr,vector<string> & fetchColumn)174 static void ConvertColumnsForPortrait(const shared_ptr<PhotoAlbum>& photoAlbumPtr, vector<string> &fetchColumn)
175 {
176     if (photoAlbumPtr == nullptr || (photoAlbumPtr->GetPhotoAlbumSubType() != PhotoAlbumSubType::PORTRAIT &&
177         !IsFeaturedSinglePortraitAlbum(photoAlbumPtr))) {
178         return;
179     }
180 
181     for (size_t i = 0; i < fetchColumn.size(); i++) {
182         if (fetchColumn[i] != "count(*)") {
183             fetchColumn[i] = PhotoColumn::PHOTOS_TABLE + "." + fetchColumn[i];
184         }
185     }
186 }
187 
GetAssets(COptions options,int32_t & errCode)188 shared_ptr<FetchResult<FileAsset>> PhotoAlbumImpl::GetAssets(COptions options, int32_t &errCode)
189 {
190     DataSharePredicates predicates;
191     vector<string> fetchColumn;
192     ExtraInfo extraInfo;
193     ParseArgsGetPhotoAssets(options, predicates, fetchColumn, extraInfo, errCode);
194     if (errCode != E_SUCCESS) {
195         LOGE("ParseArgsGetPhotoAssets failed.");
196         return nullptr;
197     }
198     Uri uri(PAH_QUERY_PHOTO_MAP);
199     ConvertColumnsForPortrait(photoAlbumPtr, fetchColumn);
200     auto resultSet = UserFileClient::Query(uri, predicates, fetchColumn, errCode);
201     if (resultSet == nullptr) {
202         LOGE("Query db failed.");
203         errCode = JS_INNER_FAIL;
204         return nullptr;
205     }
206     shared_ptr<FetchResult<FileAsset>> fetchResult = make_shared<FetchResult<FileAsset>>(move(resultSet));
207     fetchResult->SetResultNapiType(ResultNapiType::TYPE_PHOTOACCESS_HELPER);
208     return fetchResult;
209 }
210 
ParseArgsCommitModify(const shared_ptr<PhotoAlbum> & photoAlbumPtr,DataSharePredicates & predicates,DataShareValuesBucket & valuesBucket,int32_t & errCode)211 static void ParseArgsCommitModify(const shared_ptr<PhotoAlbum>& photoAlbumPtr, DataSharePredicates &predicates,
212     DataShareValuesBucket &valuesBucket, int32_t &errCode)
213 {
214     if (photoAlbumPtr == nullptr) {
215         LOGE("photoAlbumPtr is nullptr.");
216         errCode = JS_ERR_PARAMETER_INVALID;
217         return;
218     }
219     if (!PhotoAlbum::IsUserPhotoAlbum(photoAlbumPtr->GetPhotoAlbumType(), photoAlbumPtr->GetPhotoAlbumSubType())) {
220         LOGE("modify failed: not user PhotoAlbum.");
221         errCode = JS_ERR_PARAMETER_INVALID;
222         return;
223     }
224     if (MediaFileUtils::CheckAlbumName(photoAlbumPtr->GetAlbumName()) < 0) {
225         LOGE("modify failed: not user PhotoAlbum.");
226         errCode = JS_ERR_PARAMETER_INVALID;
227         return;
228     }
229     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(photoAlbumPtr->GetAlbumId()));
230     valuesBucket.Put(PhotoAlbumColumns::ALBUM_NAME, photoAlbumPtr->GetAlbumName());
231     valuesBucket.Put(PhotoAlbumColumns::ALBUM_COVER_URI, photoAlbumPtr->GetCoverUri());
232 }
233 
CommitModify(int32_t & errCode)234 void PhotoAlbumImpl::CommitModify(int32_t &errCode)
235 {
236     DataSharePredicates predicates;
237     DataShareValuesBucket valuesBucket;
238     ParseArgsCommitModify(photoAlbumPtr, predicates, valuesBucket, errCode);
239     string commitModifyUri = PAH_UPDATE_PHOTO_ALBUM;
240     Uri uri(commitModifyUri);
241     int changedRows = UserFileClient::Update(uri, predicates, valuesBucket);
242     if (changedRows < 0) {
243         errCode = MediaLibraryNapiUtils::TransErrorCode("commitModify", changedRows);
244     }
245 }
246 }
247 }