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 "oobe_datashare_utils.h"
17 #include "res_sched_log.h"
18 #include "oobe_manager.h"
19 #include <functional>
20 #include <vector>
21 #include "ipc_skeleton.h"
22 
23 namespace OHOS {
24 namespace ResourceSchedule {
25 ffrt::recursive_mutex OOBEManager::mutex_;
26 std::vector<std::shared_ptr<IOOBETask>> OOBEManager::oobeTasks_;
27 std::vector<std::function<void()>> OOBEManager::dataShareFunctions_;
28 sptr<OOBEManager::ResDataAbilityObserver> OOBEManager::observer_ = nullptr;
29 namespace {
30 const std::string KEYWORD = "basic_statement_agreed";
31 } // namespace
32 
OOBEManager()33 OOBEManager::OOBEManager()
34 {
35     Initialize();
36 }
37 
~OOBEManager()38 OOBEManager::~OOBEManager()
39 {
40     RESSCHED_LOGI("OOBEManager has been deconstructed");
41 }
42 
GetInstance()43 OOBEManager& OOBEManager::GetInstance()
44 {
45     static OOBEManager instance;
46     return instance;
47 }
48 
GetOOBValue()49 bool OOBEManager::GetOOBValue()
50 {
51     std::lock_guard<ffrt::recursive_mutex> lock(mutex_);
52     return g_oobeValue;
53 }
54 
RegisterObserver(const std::string & key,const ResDataAbilityObserver::UpdateFunc & func)55 ErrCode OOBEManager::RegisterObserver(const std::string& key, const ResDataAbilityObserver::UpdateFunc& func)
56 {
57     std::lock_guard<ffrt::recursive_mutex> lock(mutex_);
58     if (!DataShareUtils::GetInstance().IsConnectDataShareSucc()) {
59         if (DataShareUtils::GetInstance().GetDataShareReadyFlag()) {
60             RESSCHED_LOGE("dataShare is ready but conntect fail");
61             return ERR_NO_INIT;
62         }
63         RESSCHED_LOGE("RegisterObserver: dataShare is not ready!");
64         std::function dataShareFunction = [key, func, this]() {
65             ReRegisterObserver(key, func);
66         };
67         dataShareFunctions_.push_back(dataShareFunction);
68         return ERR_NO_INIT;
69     }
70 
71     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
72     auto uri = DataShareUtils::GetInstance().AssembleUri(key);
73     auto helper = DataShareUtils::GetInstance().CreateDataShareHelper();
74     if (helper == nullptr) {
75         IPCSkeleton::SetCallingIdentity(callingIdentity);
76         RESSCHED_LOGE("RegisterObserver: helper does not created!");
77         return ERR_NO_INIT;
78     }
79     if (observer_ != nullptr) {
80         RESSCHED_LOGE("Secondary RegisterObserver!");
81         UnregisterObserver();
82     }
83     observer_ = new (std::nothrow)ResDataAbilityObserver();
84     if (observer_ == nullptr) {
85         IPCSkeleton::SetCallingIdentity(callingIdentity);
86         return ERR_INVALID_OPERATION;
87     }
88     observer_->SetUpdateFunc(func);
89     helper->RegisterObserver(uri, observer_);
90     DataShareUtils::GetInstance().ReleaseDataShareHelper(helper);
91     IPCSkeleton::SetCallingIdentity(callingIdentity);
92     RESSCHED_LOGI("succeed to register observer of uri=%{public}s", uri.ToString().c_str());
93     return ERR_OK;
94 }
95 
ReRegisterObserver(const std::string & key,const ResDataAbilityObserver::UpdateFunc & func)96 void OOBEManager::ReRegisterObserver(const std::string& key, const ResDataAbilityObserver::UpdateFunc& func)
97 {
98     int resultValue = 0;
99     ResourceSchedule::DataShareUtils::GetInstance().GetValue(key, resultValue);
100     if (resultValue != 0) {
101         func();
102         return;
103     }
104     RegisterObserver(key, func);
105 }
106 
UnregisterObserver()107 ErrCode OOBEManager::UnregisterObserver()
108 {
109     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
110     auto uri = DataShareUtils::GetInstance().AssembleUri(KEYWORD);
111     auto helper = DataShareUtils::GetInstance().CreateDataShareHelper();
112     if (helper == nullptr) {
113         IPCSkeleton::SetCallingIdentity(callingIdentity);
114         RESSCHED_LOGE("UnregisterObserver: helper does not created!");
115         return ERR_NO_INIT;
116     }
117     helper->UnregisterObserver(uri, observer_);
118     DataShareUtils::GetInstance().ReleaseDataShareHelper(helper);
119     observer_ = nullptr;
120     IPCSkeleton::SetCallingIdentity(callingIdentity);
121     RESSCHED_LOGI("succeed to register observer of uri=%{public}s", uri.ToString().c_str());
122     return ERR_OK;
123 }
124 
OnChange()125 void OOBEManager::ResDataAbilityObserver::OnChange()
126 {
127     if (update_) {
128         update_();
129     }
130 }
131 
SetUpdateFunc(const UpdateFunc & func)132 void OOBEManager::ResDataAbilityObserver::SetUpdateFunc(const UpdateFunc& func)
133 {
134     update_ = func;
135 }
136 
Initialize()137 void OOBEManager::Initialize()
138 {
139     int resultValue = 0;
140     ResourceSchedule::DataShareUtils::GetInstance().GetValue(KEYWORD, resultValue);
141     if (resultValue != 0) {
142         g_oobeValue = true;
143     }
144 }
145 
SubmitTask(const std::shared_ptr<IOOBETask> & task)146 bool OOBEManager::SubmitTask(const std::shared_ptr<IOOBETask>& task)
147 {
148     std::lock_guard<ffrt::recursive_mutex> lock(mutex_);
149     if (task == nullptr) {
150         RESSCHED_LOGE("Bad task passed!");
151         return false;
152     }
153     if (g_oobeValue) {
154         task->ExcutingTask();
155         return true;
156     }
157     oobeTasks_.push_back(task);
158     return true;
159 }
160 
StartListen()161 void OOBEManager::StartListen()
162 {
163     int resultValue = 0;
164     ResourceSchedule::DataShareUtils::GetInstance().GetValue(KEYWORD, resultValue);
165     if (resultValue != 0) {
166         std::lock_guard<ffrt::recursive_mutex> lock(mutex_);
167         g_oobeValue = true;
168         for (auto task : oobeTasks_) {
169             task->ExcutingTask();
170         }
171         return;
172     }
173     OOBEManager::ResDataAbilityObserver::UpdateFunc updateFunc = [&]() {
174         int result = 0;
175         ResourceSchedule::DataShareUtils::GetInstance().GetValue(KEYWORD, result);
176         if (result != 0) {
177             RESSCHED_LOGI("User consent authorization!");
178             std::lock_guard<ffrt::recursive_mutex> lock(mutex_);
179             g_oobeValue = true;
180             for (auto task : oobeTasks_) {
181                 task->ExcutingTask();
182             }
183         } else {
184             RESSCHED_LOGI("User does not consent authorization!");
185             g_oobeValue = false;
186         }
187     };
188     RegisterObserver(KEYWORD, updateFunc);
189 }
190 
OnReceiveDataShareReadyCallBack()191 void OOBEManager::OnReceiveDataShareReadyCallBack()
192 {
193     ffrt::submit([]() {
194         DataShareUtils::GetInstance().SetDataShareReadyFlag(true);
195         OOBEManager::GetInstance().ExecuteDataShareFunction();
196         });
197 }
198 
ExecuteDataShareFunction()199 void OOBEManager::ExecuteDataShareFunction()
200 {
201     std::vector<std::function<void()>> dataShareFunctions;
202     {
203         std::lock_guard<ffrt::recursive_mutex> lock(mutex_);
204         dataShareFunctions = std::move(dataShareFunctions_);
205     }
206     for (auto function : dataShareFunctions) {
207         function();
208     }
209     RESSCHED_LOGI("execute data share function success");
210 }
211 } // namespace ResourceSchedule
212 } // namespace OHOS
213