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