1 /*
2  * Copyright (c) 2022 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 #define LOG_TAG "UdmfServiceClient"
16 #include "udmf_service_client.h"
17 
18 #include "iservice_registry.h"
19 #include "datamgr_service_proxy.h"
20 #include "system_ability_definition.h"
21 #include "unified_data_helper.h"
22 
23 #include "logger.h"
24 
25 namespace OHOS {
26 namespace UDMF {
27 std::shared_ptr<UdmfServiceClient> UdmfServiceClient::instance_;
28 std::mutex UdmfServiceClient::mutex_;
29 sptr<DistributedKv::IKvStoreDataService> UdmfServiceClient::kvDataServiceProxy_;
30 
UdmfServiceClient(const sptr<UdmfServiceProxy> & proxy)31 UdmfServiceClient::UdmfServiceClient(const sptr<UdmfServiceProxy> &proxy) : udmfProxy_(proxy)
32 {
33     LOG_INFO(UDMF_SERVICE, "construct");
34 }
35 
GetInstance()36 std::shared_ptr<UdmfServiceClient> UdmfServiceClient::GetInstance()
37 {
38     std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
39     if (instance_ != nullptr) {
40         return instance_;
41     }
42     sptr<DistributedKv::IKvStoreDataService> ability = GetDistributedKvDataService();
43     if (ability == nullptr) {
44         return nullptr;
45     }
46     sptr<IRemoteObject> service = ability->GetFeatureInterface("udmf");
47     if (service == nullptr) {
48         return nullptr;
49     }
50     sptr<UdmfServiceProxy> proxy = iface_cast<UdmfServiceProxy>(service);
51     if (proxy == nullptr) {
52         return nullptr;
53     }
54     instance_ = std::make_shared<UdmfServiceClient>(proxy);
55     return instance_;
56 }
57 
GetDistributedKvDataService()58 sptr<DistributedKv::IKvStoreDataService> UdmfServiceClient::GetDistributedKvDataService()
59 {
60     if (kvDataServiceProxy_ != nullptr) {
61         return kvDataServiceProxy_;
62     }
63     LOG_INFO(UDMF_SERVICE, "create remote proxy.");
64     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
65     if (samgr == nullptr) {
66         LOG_ERROR(UDMF_SERVICE, "get samgr fail.");
67         return nullptr;
68     }
69 
70     auto remote = samgr->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
71     kvDataServiceProxy_ = iface_cast<DistributedKv::DataMgrServiceProxy>(remote);
72     if (kvDataServiceProxy_ == nullptr) {
73         LOG_ERROR(UDMF_SERVICE, "initialize proxy failed.");
74         return nullptr;
75     }
76     sptr<UdmfServiceClient::ServiceDeathRecipient> deathRecipientPtr = new (std::nothrow)ServiceDeathRecipient();
77     if (deathRecipientPtr == nullptr) {
78         return nullptr;
79     }
80     if ((remote->IsProxyObject()) && (!remote->AddDeathRecipient(deathRecipientPtr))) {
81         LOG_ERROR(UDMF_SERVICE, "Add death recipient fail!");
82     }
83     return kvDataServiceProxy_;
84 }
85 
ServiceDeathRecipient()86 UdmfServiceClient::ServiceDeathRecipient::ServiceDeathRecipient()
87 {
88     LOG_INFO(UDMF_SERVICE, "Construct!");
89 }
90 
~ServiceDeathRecipient()91 UdmfServiceClient::ServiceDeathRecipient::~ServiceDeathRecipient()
92 {
93     LOG_INFO(UDMF_SERVICE, "Destruct!");
94 }
95 
OnRemoteDied(const wptr<IRemoteObject> & remote)96 void UdmfServiceClient::ServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
97 {
98     LOG_WARN(UDMF_SERVICE, "DistributedDataService die!");
99     std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
100     kvDataServiceProxy_ = nullptr;
101     instance_ = nullptr;
102 }
103 
SetData(CustomOption & option,UnifiedData & unifiedData,std::string & key)104 int32_t UdmfServiceClient::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
105 {
106     LOG_DEBUG(UDMF_SERVICE, "start, tag: %{public}d", option.intention);
107     if (!UnifiedDataUtils::IsValidIntention(option.intention)) {
108         LOG_ERROR(UDMF_SERVICE, "Invalid intention");
109         return E_INVALID_PARAMETERS;
110     }
111 
112     if (!unifiedData.IsValid()) {
113         LOG_ERROR(UDMF_SERVICE, "UnifiedData is invalid.");
114         return E_INVALID_PARAMETERS;
115     }
116     if (UnifiedDataHelper::ExceedKVSizeLimit(unifiedData)) {
117         if (!UnifiedDataHelper::Pack(unifiedData)) {
118             LOG_ERROR(UDMF_SERVICE, "Failed to pack unified data.");
119             return E_FS_ERROR;
120         }
121     }
122     return udmfProxy_->SetData(option, unifiedData, key);
123 }
124 
GetData(const QueryOption & query,UnifiedData & unifiedData)125 int32_t UdmfServiceClient::GetData(const QueryOption &query, UnifiedData &unifiedData)
126 {
127     LOG_DEBUG(UDMF_SERVICE, "start, tag: %{public}s", query.key.c_str());
128     UnifiedKey key(query.key);
129     if (!key.IsValid()) {
130         LOG_ERROR(UDMF_SERVICE, "invalid key");
131         return E_INVALID_PARAMETERS;
132     }
133 
134     auto err = udmfProxy_->GetData(query, unifiedData);
135     if (err == E_OK) {
136         if (UnifiedDataHelper::IsTempUData(unifiedData)) {
137             if (!UnifiedDataHelper::Unpack(unifiedData)) {
138                 LOG_ERROR(UDMF_SERVICE, "failed to unpack unified data");
139                 return E_FS_ERROR;
140             }
141         }
142     }
143     return err;
144 }
145 
GetBatchData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)146 int32_t UdmfServiceClient::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
147 {
148     LOG_DEBUG(UDMF_SERVICE, "start, tag: intention = %{public}d, key = %{public}s", query.intention, query.key.c_str());
149     auto find = UD_INTENTION_MAP.find(query.intention);
150     std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second;
151     if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) {
152         LOG_ERROR(UDMF_SERVICE, "invalid option, query.key: %{public}s, intention: %{public}s", query.key.c_str(),
153             intention.c_str());
154         return E_INVALID_PARAMETERS;
155     }
156     std::vector<UnifiedData> tempDataSet {};
157     auto err = udmfProxy_->GetBatchData(query, tempDataSet);
158     if (err != E_OK) {
159         return err;
160     }
161     for (auto &data : tempDataSet) {
162         if (UnifiedDataHelper::IsTempUData(data)) {
163             if (!UnifiedDataHelper::Unpack(data)) {
164                 LOG_ERROR(UDMF_SERVICE, "failed to unpack unified data");
165                 return E_FS_ERROR;
166             }
167         }
168         unifiedDataSet.emplace_back(data);
169     }
170     return E_OK;
171 }
172 
UpdateData(const QueryOption & query,UnifiedData & unifiedData)173 int32_t UdmfServiceClient::UpdateData(const QueryOption &query, UnifiedData &unifiedData)
174 {
175     LOG_DEBUG(UDMF_SERVICE, "start, tag: %{public}s", query.key.c_str());
176     UnifiedKey key(query.key);
177     if (!key.IsValid() || !UnifiedDataUtils::IsPersist(key.intention)) {
178         LOG_ERROR(UDMF_SERVICE, "invalid key, key.intention: %{public}s", key.intention.c_str());
179         return E_INVALID_PARAMETERS;
180     }
181 
182     if (!unifiedData.IsValid()) {
183         LOG_ERROR(UDMF_SERVICE, "UnifiedData is invalid.");
184         return E_INVALID_PARAMETERS;
185     }
186     if (UnifiedDataHelper::ExceedKVSizeLimit(unifiedData)) {
187         if (!UnifiedDataHelper::Pack(unifiedData)) {
188             LOG_ERROR(UDMF_SERVICE, "Failed to pack unified data.");
189             return E_FS_ERROR;
190         }
191     }
192     return udmfProxy_->UpdateData(query, unifiedData);
193 }
194 
DeleteData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)195 int32_t UdmfServiceClient::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
196 {
197     LOG_DEBUG(UDMF_SERVICE, "start, tag: intention = %{public}d, key = %{public}s", query.intention, query.key.c_str());
198     auto find = UD_INTENTION_MAP.find(query.intention);
199     std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second;
200     if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) {
201         LOG_ERROR(UDMF_SERVICE, "invalid option, query.key: %{public}s, intention: %{public}s", query.key.c_str(),
202             intention.c_str());
203         return E_INVALID_PARAMETERS;
204     }
205     return udmfProxy_->DeleteData(query, unifiedDataSet);
206 }
207 
GetSummary(const QueryOption & query,Summary & summary)208 int32_t UdmfServiceClient::GetSummary(const QueryOption &query, Summary &summary)
209 {
210     LOG_DEBUG(UDMF_SERVICE, "start, tag: %{public}s", query.key.c_str());
211     UnifiedKey key(query.key);
212     if (!key.IsValid()) {
213         LOG_ERROR(UDMF_SERVICE, "invalid key");
214         return E_INVALID_PARAMETERS;
215     }
216     return udmfProxy_->GetSummary(query, summary);
217 }
218 
AddPrivilege(const QueryOption & query,Privilege & privilege)219 int32_t UdmfServiceClient::AddPrivilege(const QueryOption &query, Privilege &privilege)
220 {
221     LOG_DEBUG(UDMF_SERVICE, "start, key: %{public}s", query.key.c_str());
222     UnifiedKey key(query.key);
223     if (!key.IsValid()) {
224         LOG_ERROR(UDMF_SERVICE, "invalid key");
225         return E_INVALID_PARAMETERS;
226     }
227     return udmfProxy_->AddPrivilege(query, privilege);
228 }
229 
Sync(const QueryOption & query,const std::vector<std::string> & devices)230 int32_t UdmfServiceClient::Sync(const QueryOption &query, const std::vector<std::string> &devices)
231 {
232     LOG_DEBUG(UDMF_SERVICE, "start, key: %{public}s", query.key.c_str());
233     UnifiedKey key(query.key);
234     if (!key.IsValid()) {
235         LOG_ERROR(UDMF_SERVICE, "invalid key");
236         return E_INVALID_PARAMETERS;
237     }
238     return udmfProxy_->Sync(query, devices);
239 }
240 
IsRemoteData(const QueryOption & query,bool & result)241 int32_t UdmfServiceClient::IsRemoteData(const QueryOption &query, bool &result)
242 {
243     LOG_DEBUG(UDMF_SERVICE, "start, key: %{public}s", query.key.c_str());
244     UnifiedKey key(query.key);
245     if (!key.IsValid()) {
246         LOG_ERROR(UDMF_SERVICE, "invalid key");
247         return E_INVALID_PARAMETERS;
248     }
249     return udmfProxy_->IsRemoteData(query, result);
250 }
251 
SetAppShareOption(const std::string & intention,int32_t shareOption)252 int32_t UdmfServiceClient::SetAppShareOption(const std::string &intention, int32_t shareOption)
253 {
254     LOG_DEBUG(UDMF_SERVICE, "start, intention: %{public}s, shareOption: %{public}d",
255               intention.c_str(), shareOption);
256     if (intention.empty() || shareOption < IN_APP || shareOption > CROSS_APP) {
257         LOG_ERROR(UDMF_SERVICE, "invalid parameters");
258         return E_INVALID_PARAMETERS;
259     }
260     return udmfProxy_->SetAppShareOption(intention, shareOption);
261 }
262 
GetAppShareOption(const std::string & intention,int32_t & shareOption)263 int32_t UdmfServiceClient::GetAppShareOption(const std::string &intention, int32_t &shareOption)
264 {
265     LOG_DEBUG(UDMF_SERVICE, "start, intention: %{public}s", intention.c_str());
266     if (intention.empty()) {
267         LOG_ERROR(UDMF_SERVICE, "invalid parameters");
268         return E_INVALID_PARAMETERS;
269     }
270     return udmfProxy_->GetAppShareOption(intention, shareOption);
271 }
272 
RemoveAppShareOption(const std::string & intention)273 int32_t UdmfServiceClient::RemoveAppShareOption(const std::string &intention)
274 {
275     LOG_DEBUG(UDMF_SERVICE, "start, intention: %{public}s", intention.c_str());
276     if (intention.empty()) {
277         LOG_ERROR(UDMF_SERVICE, "invalid parameters");
278         return E_INVALID_PARAMETERS;
279     }
280     return udmfProxy_->RemoveAppShareOption(intention);
281 }
282 } // namespace UDMF
283 } // namespace OHOS