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 <vector>
17 #include <string>
18 
19 #include "cloud_sync_observer.h"
20 
21 #include "cloud_sync_notify_handler.h"
22 #include "media_analysis_helper.h"
23 #include "medialibrary_unistore_manager.h"
24 #include "media_column.h"
25 #include "media_log.h"
26 #include "result_set_utils.h"
27 
28 using namespace std;
29 
30 namespace OHOS {
31 namespace Media {
32 constexpr int32_t SYNC_INTERVAL = 10000;
HandleCloudNotify(AsyncTaskData * data)33 static void HandleCloudNotify(AsyncTaskData *data)
34 {
35     auto* taskData = static_cast<CloudSyncNotifyData*>(data);
36     shared_ptr<CloudSyncNotifyHandler> notifyHandler = make_shared<CloudSyncNotifyHandler>(taskData->notifyInfo_);
37     notifyHandler->MakeResponsibilityChain();
38 }
39 
CloudSyncObserver()40 CloudSyncObserver::CloudSyncObserver() : timer_("CloudSyncObserver")
41 {
42     timer_.Setup();
43 }
44 
OnChange(const ChangeInfo & changeInfo)45 void CloudSyncObserver::OnChange(const ChangeInfo &changeInfo)
46 {
47     CloudSyncNotifyInfo notifyInfo = {changeInfo.uris_, changeInfo.changeType_};
48     string uriString = notifyInfo.uris.front().ToString();
49     if (uriString.find(PhotoColumn::PHOTO_CLOUD_URI_PREFIX) != string::npos && notifyInfo.type == ChangeType::OTHER) {
50         lock_guard<mutex> lock(syncMutex_);
51         if (!isPending_) {
52             MEDIA_INFO_LOG("set timer handle index");
53             timerId_ = timer_.Register(bind(&CloudSyncObserver::HandleIndex, this), SYNC_INTERVAL, true);
54             isPending_ = true;
55         }
56     }
57 
58     auto *taskData = new (nothrow) CloudSyncNotifyData(notifyInfo);
59     if (taskData == nullptr) {
60         MEDIA_ERR_LOG("Failed to new taskData");
61         return;
62     }
63     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
64     if (asyncWorker == nullptr) {
65         MEDIA_ERR_LOG("Can not get asyncWorker");
66         delete taskData;
67         return;
68     }
69     shared_ptr<MediaLibraryAsyncTask> notifyHandleAsyncTask = make_shared<MediaLibraryAsyncTask>(
70         HandleCloudNotify, taskData);
71     if (notifyHandleAsyncTask != nullptr) {
72         asyncWorker->AddTask(notifyHandleAsyncTask, true);
73     }
74 }
75 
HandleIndex()76 void CloudSyncObserver::HandleIndex()
77 {
78     lock_guard<mutex> lock(syncMutex_);
79     std::vector<std::string> idToDeleteIndex;
80     MediaAnalysisHelper::AsyncStartMediaAnalysisService(
81         static_cast<int32_t>(MediaAnalysisProxy::ActivateServiceType::START_DELETE_INDEX), idToDeleteIndex);
82 
83     //update index
84     auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
85     if (uniStore == nullptr) {
86         MEDIA_ERR_LOG("uniStore is nullptr!");
87         return;
88     }
89     const std::string queryIdToUpdateIndex = "SELECT file_id FROM tab_analysis_search_index WHERE photo_status = 2";
90     auto resultSetUpdateIndex = uniStore->QuerySql(queryIdToUpdateIndex);
91     if (resultSetUpdateIndex == nullptr) {
92         MEDIA_ERR_LOG("resultSetUpdateIndex is nullptr!");
93         return;
94     }
95     std::vector<std::string> idToUpdateIndex;
96     while (resultSetUpdateIndex->GoToNextRow() == NativeRdb::E_OK) {
97         idToUpdateIndex.push_back(to_string(GetInt32Val("file_id", resultSetUpdateIndex)));
98     }
99     MEDIA_INFO_LOG("HandleIndex idToUpdateIndex size: %{public}zu", idToUpdateIndex.size());
100     if (!idToUpdateIndex.empty()) {
101         MediaAnalysisHelper::AsyncStartMediaAnalysisService(
102             static_cast<int32_t>(MediaAnalysisProxy::ActivateServiceType::START_UPDATE_INDEX), idToUpdateIndex);
103     }
104     isPending_ = false;
105 }
106 } // namespace Media
107 } // namespace OHOS
108