• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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_facard_operations.h"
17 
18 #include <memory>
19 #include <mutex>
20 #include <string>
21 #include "abs_shared_result_set.h"
22 
23 #include "media_column.h"
24 #include "media_file_uri.h"
25 #include "media_file_utils.h"
26 #include "media_log.h"
27 #include "medialibrary_errno.h"
28 #include "medialibrary_object_utils.h"
29 #include "medialibrary_rdbstore.h"
30 #include "rdb_predicates.h"
31 #include "result_set_utils.h"
32 #include "value_object.h"
33 #include "values_bucket.h"
34 #include "datashare_helper.h"
35 #include "medialibrary_data_manager.h"
36 #include "media_facard_photos_column.h"
37 #include "result_set_utils.h"
38 #include "ability_manager_client.h"
39 #include "application_context.h"
40 #include "resource_type.h"
41 
42 using namespace OHOS::DataShare;
43 using ChangeType = OHOS::DataShare::DataShareObserver::ChangeType;
44 using namespace std;
45 using namespace OHOS::NativeRdb;
46 
47 namespace OHOS {
48 namespace Media {
49 std::mutex MediaLibraryFaCardOperations::mutex_;
50 const string MEDIA_LIBRARY_PROXY_URI = "datashareproxy://com.ohos.medialibrary.medialibrarydata";
51 static std::map<std::string, std::vector<std::shared_ptr<CardAssetUriObserver>>> formAssetObserversMap;
52 static std::map<ChangeType, int> changeTypeMap = {
53     { ChangeType::INSERT, 0 },
54     { ChangeType::DELETE, 1 },
55     { ChangeType::UPDATE, 2 },
56     { ChangeType::OTHER, 3 },
57     { ChangeType::INVAILD, 4 },
58 };
59 
60 bool CardAssetUriObserver::isTaskPosted = false;
61 std::shared_ptr<AppExecFwk::EventHandler> CardAssetUriObserver::deviceHandler_ =
62 std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::Create("MediaLibraryFacard"));
63 std::mutex CardAssetUriObserver::mtx;
64 std::unordered_set<
65     CardAssetUriObserver::AssetChangeInfo,
66     CardAssetUriObserver::AssetChangeInfoHash> CardAssetUriObserver::assetChanges;
67 
GetUris()68 std::map<std::string, std::vector<std::string>> MediaLibraryFaCardOperations::GetUris()
69 {
70     lock_guard<mutex> lock(mutex_);
71     MediaLibraryCommand queryFaCardCmd(OperationObject::TAB_FACARD_PHOTO, OperationType::QUERY);
72     std::map<std::string, std::vector<std::string>> resultMap;
73     auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
74     if (uniStore == nullptr) {
75         MEDIA_ERR_LOG("UniStore is nullptr");
76         return resultMap;
77     }
78     vector<string> columns = {
79         TabFaCardPhotosColumn::FACARD_PHOTOS_ASSET_URI,
80         TabFaCardPhotosColumn::FACARD_PHOTOS_FORM_ID
81     };
82     auto queryResult = uniStore->Query(queryFaCardCmd, columns);
83     if (queryResult == nullptr) {
84         MEDIA_ERR_LOG("Failed to query assetUris!");
85         return resultMap;
86     }
87     while (queryResult->GoToNextRow() == NativeRdb::E_OK) {
88         string assetUri = GetStringVal(TabFaCardPhotosColumn::FACARD_PHOTOS_ASSET_URI, queryResult);
89         string formId = GetStringVal(TabFaCardPhotosColumn::FACARD_PHOTOS_FORM_ID, queryResult);
90         resultMap[formId].push_back(assetUri);
91     }
92     return resultMap;
93 }
94 
GetStringObject(MediaLibraryCommand & cmd,const string & columnName)95 static string GetStringObject(MediaLibraryCommand &cmd, const string &columnName)
96 {
97     ValueObject valueObject;
98     ValuesBucket values = cmd.GetValueBucket();
99     string value;
100     if (values.GetObject(columnName, valueObject)) {
101         valueObject.GetString(value);
102         return value;
103     }
104     return "";
105 }
106 
PostAssetChangeTask()107 void CardAssetUriObserver::PostAssetChangeTask()
108 {
109     if (!CardAssetUriObserver::isTaskPosted) {
110         CardAssetUriObserver::isTaskPosted = true;
111         const int DELAY_MILLISECONDS = 2000;
112         CardAssetUriObserver::deviceHandler_->PostTask([this]() {
113             std::lock_guard<std::mutex> lock(CardAssetUriObserver::mtx);
114             std::vector<std::string> assetChangeUris;
115             std::vector<int> assetChangeTypes;
116             for (const auto& change : CardAssetUriObserver::assetChanges) {
117                 assetChangeUris.push_back(change.assetChangeUri);
118                 MEDIA_DEBUG_LOG("change.assetChangeUri = %{public}s", change.assetChangeUri.c_str());
119                 assetChangeTypes.push_back(change.assetChangeType);
120                 MEDIA_DEBUG_LOG("change.assetChangeType = %{public}d", change.assetChangeType);
121             }
122             AAFwk::Want want;
123             want.SetElementName("com.huawei.hmos.photos", "FACardServiceAbility");
124             want.SetParam("assetChangeUris", assetChangeUris);
125             want.SetParam("assetChangeTypes", assetChangeTypes);
126             int32_t userId = -1;
127             auto result = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(
128                 want, nullptr, userId, AppExecFwk::ExtensionAbilityType::SERVICE);
129             CardAssetUriObserver::assetChanges.clear();
130             CardAssetUriObserver::isTaskPosted = false;
131             }, "StartExtensionAbility", DELAY_MILLISECONDS);
132     }
133 }
134 
OnChange(const ChangeInfo & changeInfo)135 void CardAssetUriObserver::OnChange(const ChangeInfo &changeInfo)
136 {
137     if (changeTypeMap.find(changeInfo.changeType_) != changeTypeMap.end()) {
138         std::lock_guard<std::mutex> lock(CardAssetUriObserver::mtx);
139         MEDIA_DEBUG_LOG("OnChange assetChangeUri = %{public}s", assetChangeUri.c_str());
140         MEDIA_DEBUG_LOG("OnChange assetChangeType = %{public}d", static_cast<int>(changeInfo.changeType_));
141         CardAssetUriObserver::assetChanges.insert(
142             AssetChangeInfo(assetChangeUri, static_cast<int>(changeInfo.changeType_)));
143 
144         PostAssetChangeTask();
145     }
146 }
147 
RegisterObserver(const std::string & formId,const std::string & registerUri)148 void MediaLibraryFaCardOperations::RegisterObserver(const std::string &formId, const std::string &registerUri)
149 {
150     const std::string ASSET_URI_PREFIX = "file://media/";
151     const std::string CLOUD_SYNC_SWITCH_URI_PREFIX = "datashareproxy://";
152     MEDIA_DEBUG_LOG("registerUri = %{public}s", registerUri.c_str());
153 
154     std::shared_ptr<DataShare::DataShareObserver> observer;
155     if (registerUri.find(ASSET_URI_PREFIX) == 0 || registerUri.find(CLOUD_SYNC_SWITCH_URI_PREFIX) == 0) {
156         auto cardAssetUriObserver = std::make_shared<CardAssetUriObserver>(registerUri);
157         MEDIA_DEBUG_LOG("cardAssetUriObserver->uri = %{public}s", cardAssetUriObserver->assetChangeUri.c_str());
158         formAssetObserversMap[formId].push_back(cardAssetUriObserver);
159         observer = std::static_pointer_cast<DataShare::DataShareObserver>(cardAssetUriObserver);
160     } else {
161         MEDIA_ERR_LOG("registerUri is inValid");
162         return;
163     }
164     Uri notifyUri(registerUri);
165     CreateOptions options;
166     options.enabled_ = true;
167     shared_ptr<DataShare::DataShareHelper> dataShareHelper =
168     DataShare::DataShareHelper::Creator(MEDIA_LIBRARY_PROXY_URI, options);
169     if (dataShareHelper == nullptr) {
170         MEDIA_ERR_LOG("dataShareHelper is nullptr");
171         return;
172     }
173     MEDIA_DEBUG_LOG("notifyUri = %{public}s", notifyUri.ToString().c_str());
174     dataShareHelper->RegisterObserverExt(notifyUri, observer, true);
175 }
176 
UnregisterObserver(const std::string & formId)177 void MediaLibraryFaCardOperations::UnregisterObserver(const std::string &formId)
178 {
179     CreateOptions options;
180     options.enabled_ = true;
181     shared_ptr<DataShare::DataShareHelper> dataShareHelper =
182     DataShare::DataShareHelper::Creator(MEDIA_LIBRARY_PROXY_URI, options);
183     if (dataShareHelper == nullptr) {
184         MEDIA_ERR_LOG("dataShareHelper is nullptr");
185         return;
186     }
187     auto itAsset = formAssetObserversMap.find(formId);
188     if (itAsset == formAssetObserversMap.end()) {
189         MEDIA_ERR_LOG("No formAssetObservers found for formId: %{public}s", formId.c_str());
190         return;
191     }
192     const std::vector<std::shared_ptr<CardAssetUriObserver>>& formAssetObservers = itAsset->second;
193     for (const auto& observer : formAssetObservers) {
194         Uri notifyUri(observer->assetChangeUri);
195         dataShareHelper->UnregisterObserverExt(notifyUri,
196             std::static_pointer_cast<DataShare::DataShareObserver>(observer));
197     }
198     formAssetObserversMap.erase(formId);
199 }
200 
HandleStoreGalleryFormOperation(MediaLibraryCommand & cmd)201 int32_t MediaLibraryFaCardOperations::HandleStoreGalleryFormOperation(MediaLibraryCommand &cmd)
202 {
203     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
204     if (rdbStore == nullptr) {
205         return E_HAS_DB_ERROR;
206     }
207     int64_t outRowId = -1;
208     lock_guard<mutex> lock(mutex_);
209     int32_t errCode = rdbStore->Insert(cmd, outRowId);
210     if (errCode != NativeRdb::E_OK || outRowId < 0) {
211         MEDIA_ERR_LOG("Insert into db failed, errCode = %{public}d", errCode);
212         return E_HAS_DB_ERROR;
213     }
214     string formId = GetStringObject(cmd, TabFaCardPhotosColumn::FACARD_PHOTOS_FORM_ID);
215     MEDIA_DEBUG_LOG("formId = %{public}s", formId.c_str());
216     string assetRegisterUri = GetStringObject(cmd, TabFaCardPhotosColumn::FACARD_PHOTOS_ASSET_URI);
217     MEDIA_DEBUG_LOG("assetRegisterUri = %{public}s", assetRegisterUri.c_str());
218     MediaLibraryFaCardOperations::RegisterObserver(formId, assetRegisterUri);
219     return static_cast<int32_t>(outRowId);
220 }
221 
HandleRemoveGalleryFormOperation(NativeRdb::RdbPredicates & rdbPredicate)222 int32_t MediaLibraryFaCardOperations::HandleRemoveGalleryFormOperation(NativeRdb::RdbPredicates &rdbPredicate)
223 {
224     lock_guard<mutex> lock(mutex_);
225     string formId = rdbPredicate.GetWhereArgs()[0];
226     MediaLibraryFaCardOperations::UnregisterObserver(formId);
227     return MediaLibraryRdbStore::Delete(rdbPredicate);
228 }
229 } // namespace Media
230 } // namespace OHOS