1/*
2 * Copyright (c) 2023 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 "UdmfClient"
16#include "udmf_client.h"
17
18#include "dds_trace.h"
19#include "udmf_radar_reporter.h"
20
21#include "logger.h"
22#include "udmf_service_client.h"
23#include "udmf_utils.h"
24#include "accesstoken_kit.h"
25#include "ipc_skeleton.h"
26#include "unified_data_helper.h"
27
28namespace OHOS {
29namespace UDMF {
30constexpr const char *TAG = "UdmfClient::";
31using namespace OHOS::DistributedDataDfx;
32using namespace RadarReporter;
33UdmfClient &UdmfClient::GetInstance()
34{
35    static UdmfClient instance;
36    return instance;
37}
38
39Status UdmfClient::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
40{
41    DdsTrace trace(
42        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
43    RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
44        BizScene::SET_DATA, SetDataStage::SET_DATA_BEGIN, StageRes::IDLE, BizState::DFX_BEGIN);
45    auto service = UdmfServiceClient::GetInstance();
46    if (service == nullptr) {
47        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
48        RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
49            BizScene::SET_DATA, SetDataStage::SET_DATA_BEGIN, StageRes::FAILED, E_IPC, BizState::DFX_ABNORMAL_END);
50        return E_IPC;
51    }
52
53    if (option.intention == UD_INTENTION_DRAG) {
54        ShareOptions shareOption = SHARE_OPTIONS_BUTT;
55        auto status = GetAppShareOption(UD_INTENTION_MAP.at(option.intention), shareOption);
56        if (status != E_NOT_FOUND && status != E_OK) {
57            LOG_ERROR(UDMF_CLIENT, "get appShareOption fail, intention:%{public}s",
58                      UD_INTENTION_MAP.at(option.intention).c_str());
59            return static_cast<Status>(status);
60        }
61        if (shareOption == ShareOptions::IN_APP) {
62            std::string bundleName = "udmf.inapp.data";
63            UnifiedKey udKey = UnifiedKey(UD_INTENTION_MAP.at(option.intention), bundleName, UTILS::GenerateId());
64            key = udKey.GetUnifiedKey();
65            dataCache_.Clear();
66            dataCache_.Insert(key, unifiedData);
67            LOG_INFO(UDMF_CLIENT, "SetData in app success, bundleName:%{public}s.", bundleName.c_str());
68            RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
69                BizScene::SET_DATA, SetDataStage::SET_DATA_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END);
70            return E_OK;
71        }
72    }
73    int32_t ret = service->SetData(option, unifiedData, key);
74    if (ret != E_OK) {
75        RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
76            BizScene::SET_DATA, SetDataStage::SET_DATA_END, StageRes::FAILED, ret, BizState::DFX_ABNORMAL_END);
77        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
78    }
79    RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
80        BizScene::SET_DATA, SetDataStage::SET_DATA_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END);
81    return static_cast<Status>(ret);
82}
83
84Status UdmfClient::GetData(const QueryOption &query, UnifiedData &unifiedData)
85{
86    DdsTrace trace(
87        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
88    RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
89        BizScene::GET_DATA, GetDataStage::GET_DATA_BEGIN, StageRes::IDLE, BizState::DFX_BEGIN);
90    auto service = UdmfServiceClient::GetInstance();
91    if (service == nullptr) {
92        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
93        RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
94            BizScene::GET_DATA, GetDataStage::GET_DATA_BEGIN, StageRes::FAILED, E_IPC, BizState::DFX_ABNORMAL_END);
95        return E_IPC;
96    }
97    auto it = dataCache_.Find(query.key);
98    if (it.first) {
99        unifiedData = it.second;
100        dataCache_.Erase(query.key);
101        RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
102            BizScene::GET_DATA, GetDataStage::GET_DATA_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END);
103        return E_OK;
104    }
105    LOG_WARN(UDMF_CLIENT, "query data from cache failed! key = %{public}s", query.key.c_str());
106    int32_t ret = service->GetData(query, unifiedData);
107    if (ret != E_OK) {
108        RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
109            BizScene::GET_DATA, GetDataStage::GET_DATA_END, StageRes::FAILED, ret, BizState::DFX_ABNORMAL_END);
110        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
111    }
112    RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
113        BizScene::GET_DATA, GetDataStage::GET_DATA_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END);
114    return static_cast<Status>(ret);
115}
116
117Status UdmfClient::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
118{
119    DdsTrace trace(
120        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
121    auto service = UdmfServiceClient::GetInstance();
122    if (service == nullptr) {
123        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
124        return E_IPC;
125    }
126    int32_t ret = service->GetBatchData(query, unifiedDataSet);
127    if (ret != E_OK) {
128        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
129    }
130    return static_cast<Status>(ret);
131}
132
133Status UdmfClient::UpdateData(const QueryOption &query, UnifiedData &unifiedData)
134{
135    DdsTrace trace(
136        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
137    auto service = UdmfServiceClient::GetInstance();
138    if (service == nullptr) {
139        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
140        return E_IPC;
141    }
142    int32_t ret = service->UpdateData(query, unifiedData);
143    if (ret != E_OK) {
144        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
145    }
146    return static_cast<Status>(ret);
147}
148
149Status UdmfClient::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
150{
151    DdsTrace trace(
152        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
153    auto service = UdmfServiceClient::GetInstance();
154    if (service == nullptr) {
155        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
156        return E_IPC;
157    }
158    int32_t ret = service->DeleteData(query, unifiedDataSet);
159    if (ret != E_OK) {
160        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
161    }
162    return static_cast<Status>(ret);
163}
164
165Status UdmfClient::GetSummary(const QueryOption &query, Summary &summary)
166{
167    DdsTrace trace(
168        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
169    auto service = UdmfServiceClient::GetInstance();
170    if (service == nullptr) {
171        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
172        return E_IPC;
173    }
174    auto it = dataCache_.Find(query.key);
175    if (it.first) {
176        UnifiedDataHelper::GetSummary(it.second, summary);
177        LOG_INFO(UDMF_CLIENT, "GetSummary in cache! key = %{public}s", query.key.c_str());
178        return E_OK;
179    }
180
181    int32_t ret = service->GetSummary(query, summary);
182    if (ret != E_OK) {
183        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
184    }
185    return static_cast<Status>(ret);
186}
187
188Status UdmfClient::AddPrivilege(const QueryOption &query, Privilege &privilege)
189{
190    DdsTrace trace(
191        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
192    auto service = UdmfServiceClient::GetInstance();
193    if (service == nullptr) {
194        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
195        return E_IPC;
196    }
197    int32_t ret = service->AddPrivilege(query, privilege);
198    if (ret != E_OK) {
199        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
200    }
201    return static_cast<Status>(ret);
202}
203
204Status UdmfClient::Sync(const QueryOption &query, const std::vector<std::string> &devices)
205{
206    DdsTrace trace(
207        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
208    auto service = UdmfServiceClient::GetInstance();
209    if (service == nullptr) {
210        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
211        return E_IPC;
212    }
213    int32_t ret = service->Sync(query, devices);
214    if (ret != E_OK) {
215        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
216    }
217    return static_cast<Status>(ret);
218}
219
220Status UdmfClient::IsRemoteData(const QueryOption &query, bool &result)
221{
222    DdsTrace trace(
223        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
224    auto service = UdmfServiceClient::GetInstance();
225    if (service == nullptr) {
226        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
227        return E_IPC;
228    }
229    int32_t ret = service->IsRemoteData(query, result);
230    if (ret != E_OK) {
231        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
232    }
233    return static_cast<Status>(ret);
234}
235
236Status UdmfClient::SetAppShareOption(const std::string &intention, enum ShareOptions shareOption)
237{
238    DdsTrace trace(
239        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
240    auto service = UdmfServiceClient::GetInstance();
241    if (service == nullptr) {
242        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
243        return E_IPC;
244    }
245    int32_t ret = service->SetAppShareOption(intention, shareOption);
246    if (ret != E_OK) {
247        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
248    }
249    return static_cast<Status>(ret);
250}
251
252Status UdmfClient::GetAppShareOption(const std::string &intention, enum ShareOptions &shareOption)
253{
254    DdsTrace trace(
255        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
256    auto service = UdmfServiceClient::GetInstance();
257    if (service == nullptr) {
258        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
259        return E_IPC;
260    }
261    int32_t shareOptionRet = SHARE_OPTIONS_BUTT;
262    int32_t ret = service->GetAppShareOption(intention, shareOptionRet);
263    if (ShareOptionsUtil::IsValid(shareOptionRet)) {
264        shareOption = static_cast<ShareOptions>(shareOptionRet);
265    }
266    if (ret != E_OK) {
267        LOG_INFO(UDMF_CLIENT, "No share option was obtained, ret = %{public}d", ret);
268    }
269    return static_cast<Status>(ret);
270}
271
272
273Status UdmfClient::RemoveAppShareOption(const std::string &intention)
274{
275    DdsTrace trace(
276        std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
277    auto service = UdmfServiceClient::GetInstance();
278    if (service == nullptr) {
279        LOG_ERROR(UDMF_CLIENT, "Service unavailable");
280        return E_IPC;
281    }
282    int32_t ret = service->RemoveAppShareOption(intention);
283    if (ret != E_OK) {
284        LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret);
285    }
286    return static_cast<Status>(ret);
287}
288
289std::string UdmfClient::GetSelfBundleName()
290{
291    uint32_t tokenId = IPCSkeleton::GetSelfTokenID();
292    Security::AccessToken::HapTokenInfo hapInfo;
293    if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo)
294        != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
295        return "";
296    }
297    return hapInfo.bundleName;
298}
299
300Status UdmfClient::GetDataAsync(const QueryOption &query, ObtainDataCallback callback)
301{
302    asyncObtainData_.ClearTask();
303
304    auto it = this->dataCache_.Find(query.key);
305    if (it.first) {
306        dataCache_.Erase(query.key);
307        ProgressInfo info{ "Local", ASYNC_SUCCESS, 100 };
308        callback(info, it.second);
309        return E_OK;
310    }
311
312    auto ret = asyncObtainData_.InitTask(query, callback);
313    if (ret == E_OK) {
314        ret = asyncObtainData_.RunTask();
315    }
316    if (ret != E_OK) {
317        LOG_ERROR(UDMF_CLIENT, "InitTask or RunTask faile ret=%{public}d", ret);
318        asyncObtainData_.ClearTask();
319        return ret;
320    }
321    return E_OK;
322}
323} // namespace UDMF
324} // namespace OHOS