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
16 #include "udmf_service_proxy.h"
17
18 #include "ipc_types.h"
19
20 #include "logger.h"
21 #include "tlv_util.h"
22 #include "udmf_types_util.h"
23
24 namespace OHOS {
25 namespace UDMF {
26 #define IPC_SEND(code, reply, ...) \
27 ({ \
28 int32_t __status = E_OK; \
29 do { \
30 MessageParcel request; \
31 if (!request.WriteInterfaceToken(GetDescriptor())) { \
32 __status = E_WRITE_PARCEL_ERROR; \
33 break; \
34 } \
35 if (!ITypesUtil::Marshal(request, ##__VA_ARGS__)) { \
36 __status = E_WRITE_PARCEL_ERROR; \
37 break; \
38 } \
39 MessageOption option; \
40 auto result = SendRequest(code, request, reply, option); \
41 if (result != 0) { \
42 LOG_ERROR(UDMF_SERVICE, "SendRequest failed, result = %{public}d!", result); \
43 __status = E_IPC; \
44 break; \
45 } \
46 \
47 ITypesUtil::Unmarshal(reply, __status); \
48 } while (0); \
49 __status; \
50 })
51
UdmfServiceProxy(const sptr<IRemoteObject> & object)52 UdmfServiceProxy::UdmfServiceProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<IUdmfService>(object)
53 {
54 }
55
SetData(CustomOption & option,UnifiedData & unifiedData,std::string & key)56 int32_t UdmfServiceProxy::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
57 {
58 LOG_DEBUG(UDMF_SERVICE, "start, tag: %{public}d", option.intention);
59 if (!UnifiedDataUtils::IsValidIntention(option.intention)) {
60 LOG_ERROR(UDMF_SERVICE, "Invalid intention");
61 return E_INVALID_PARAMETERS;
62 }
63 if (unifiedData.IsEmpty()) {
64 LOG_ERROR(UDMF_SERVICE, "Empty data without any record!");
65 return E_INVALID_PARAMETERS;
66 }
67 if (unifiedData.GetSize() > UdmfService::MAX_DATA_SIZE) {
68 LOG_ERROR(UDMF_SERVICE, "Exceeded the limit!");
69 return E_INVALID_PARAMETERS;
70 }
71 for (const auto &record : unifiedData.GetRecords()) {
72 if (record == nullptr) {
73 LOG_ERROR(UDMF_SERVICE, "record is nullptr!");
74 return E_INVALID_PARAMETERS;
75 }
76 if (record->GetSize() > UdmfService::MAX_RECORD_SIZE) {
77 LOG_ERROR(UDMF_SERVICE, "Exceeded record limit!");
78 return E_INVALID_PARAMETERS;
79 }
80 }
81 MessageParcel reply;
82 int32_t status = IPC_SEND(UdmfServiceInterfaceCode::SET_DATA, reply, option, unifiedData);
83 if (status != E_OK) {
84 LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x!", status);
85 return status;
86 }
87 if (!ITypesUtil::Unmarshal(reply, key)) {
88 LOG_ERROR(UDMF_SERVICE, "Unmarshal status failed!");
89 return E_READ_PARCEL_ERROR;
90 }
91 return status;
92 }
93
GetData(const QueryOption & query,UnifiedData & unifiedData)94 int32_t UdmfServiceProxy::GetData(const QueryOption &query, UnifiedData &unifiedData)
95 {
96 LOG_DEBUG(UDMF_SERVICE, "start, tag: %{public}s", query.key.c_str());
97 UnifiedKey key(query.key);
98 if (!key.IsValid()) {
99 LOG_ERROR(UDMF_SERVICE, "invalid key");
100 return E_INVALID_PARAMETERS;
101 }
102 MessageParcel reply;
103 int32_t status = IPC_SEND(UdmfServiceInterfaceCode::GET_DATA, reply, query);
104 if (status != E_OK) {
105 LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x, key:%{public}s!", status, query.key.c_str());
106 return status;
107 }
108 if (!ITypesUtil::Unmarshal(reply, unifiedData)) {
109 LOG_ERROR(UDMF_SERVICE, "Unmarshal UnifiedData failed!");
110 return E_READ_PARCEL_ERROR;
111 }
112 return status;
113 }
114
GetBatchData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)115 int32_t UdmfServiceProxy::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
116 {
117 LOG_DEBUG(UDMF_SERVICE, "start, tag: intention = %{public}d, key = %{public}s", query.intention, query.key.c_str());
118 auto find = UD_INTENTION_MAP.find(query.intention);
119 std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second;
120 if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) {
121 LOG_ERROR(UDMF_SERVICE, "invalid option");
122 return E_INVALID_PARAMETERS;
123 }
124 MessageParcel reply;
125 int32_t status = IPC_SEND(UdmfServiceInterfaceCode::GET_BATCH_DATA, reply, query);
126 if (status != E_OK) {
127 LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x, key:%{public}s, intention:%{public}d!", status,
128 query.key.c_str(), query.intention);
129 return status;
130 }
131 if (!ITypesUtil::Unmarshal(reply, unifiedDataSet)) {
132 LOG_ERROR(UDMF_SERVICE, "Unmarshal unifiedDataSet failed!");
133 return E_READ_PARCEL_ERROR;
134 }
135 return status;
136 }
137
UpdateData(const QueryOption & query,UnifiedData & unifiedData)138 int32_t UdmfServiceProxy::UpdateData(const QueryOption &query, UnifiedData &unifiedData)
139 {
140 LOG_DEBUG(UDMF_SERVICE, "start, tag: %{public}s", query.key.c_str());
141 UnifiedKey key(query.key);
142 if (!key.IsValid() || !UnifiedDataUtils::IsPersist(key.intention)) {
143 LOG_ERROR(UDMF_SERVICE, "invalid key");
144 return E_INVALID_PARAMETERS;
145 }
146 if (unifiedData.GetSize() > UdmfService::MAX_DATA_SIZE) {
147 LOG_ERROR(UDMF_SERVICE, "Exceeded the limit!");
148 return E_INVALID_PARAMETERS;
149 }
150 if (unifiedData.IsEmpty()) {
151 LOG_ERROR(UDMF_SERVICE, "Empty data without any record!");
152 return E_INVALID_PARAMETERS;
153 }
154 for (const auto &record : unifiedData.GetRecords()) {
155 if (record == nullptr) {
156 LOG_ERROR(UDMF_SERVICE, "record is nullptr!");
157 return E_INVALID_PARAMETERS;
158 }
159 if (record->GetSize() > UdmfService::MAX_RECORD_SIZE) {
160 LOG_ERROR(UDMF_SERVICE, "Exceeded record limit!");
161 return E_INVALID_PARAMETERS;
162 }
163 }
164 MessageParcel reply;
165 int32_t status = IPC_SEND(UdmfServiceInterfaceCode::UPDATE_DATA, reply, query, unifiedData);
166 if (status != E_OK) {
167 LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x!", status);
168 return status;
169 }
170 return status;
171 }
172
DeleteData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)173 int32_t UdmfServiceProxy::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
174 {
175 LOG_DEBUG(UDMF_SERVICE, "start, tag: intention = %{public}d, key = %{public}s", query.intention, query.key.c_str());
176 auto find = UD_INTENTION_MAP.find(query.intention);
177 std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second;
178 if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) {
179 LOG_ERROR(UDMF_SERVICE, "invalid option");
180 return E_INVALID_PARAMETERS;
181 }
182 MessageParcel reply;
183 int32_t status = IPC_SEND(UdmfServiceInterfaceCode::DELETE_DATA, reply, query);
184 if (status != E_OK) {
185 LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x,key: %{public}s, intention:%{public}s", status, query.key.c_str(),
186 UD_INTENTION_MAP.at(query.intention).c_str());
187 return status;
188 }
189 if (!ITypesUtil::Unmarshal(reply, unifiedDataSet)) {
190 LOG_ERROR(UDMF_SERVICE, "Unmarshal unifiedDataSet failed!");
191 return E_READ_PARCEL_ERROR;
192 }
193 LOG_DEBUG(UDMF_SERVICE, "end.");
194 return status;
195 }
196
GetSummary(const QueryOption & query,Summary & summary)197 int32_t UdmfServiceProxy::GetSummary(const QueryOption &query, Summary &summary)
198 {
199 LOG_DEBUG(UDMF_SERVICE, "start, tag: %{public}s", query.key.c_str());
200 UnifiedKey key(query.key);
201 if (!key.IsValid()) {
202 LOG_ERROR(UDMF_SERVICE, "invalid key");
203 return E_INVALID_PARAMETERS;
204 }
205 MessageParcel reply;
206 int32_t status = IPC_SEND(UdmfServiceInterfaceCode::GET_SUMMARY, reply, query);
207 if (status != E_OK) {
208 LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x, key:%{public}s!", status, query.key.c_str());
209 return status;
210 }
211 if (!ITypesUtil::Unmarshal(reply, summary)) {
212 LOG_ERROR(UDMF_SERVICE, "Unmarshal summary failed!");
213 return E_READ_PARCEL_ERROR;
214 }
215 LOG_DEBUG(UDMF_SERVICE, "end.");
216 return status;
217 }
218
AddPrivilege(const QueryOption & query,Privilege & privilege)219 int32_t UdmfServiceProxy::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 MessageParcel reply;
228 int32_t status = IPC_SEND(UdmfServiceInterfaceCode::ADD_PRIVILEGE, reply, query, privilege);
229 if (status != E_OK) {
230 LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x, key:%{public}s", status, query.key.c_str());
231 }
232 LOG_DEBUG(UDMF_SERVICE, "end.");
233 return status;
234 }
235
Sync(const QueryOption & query,const std::vector<std::string> & devices)236 int32_t UdmfServiceProxy::Sync(const QueryOption &query, const std::vector<std::string> &devices)
237 {
238 LOG_DEBUG(UDMF_SERVICE, "start, key: %{public}s", query.key.c_str());
239 UnifiedKey key(query.key);
240 if (!key.IsValid()) {
241 LOG_ERROR(UDMF_SERVICE, "invalid key");
242 return E_INVALID_PARAMETERS;
243 }
244 MessageParcel reply;
245 int32_t status = IPC_SEND(UdmfServiceInterfaceCode::SYNC, reply, query, devices);
246 if (status != E_OK) {
247 LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x, key:%{public}s", status, query.key.c_str());
248 }
249 LOG_DEBUG(UDMF_SERVICE, "end.");
250 return status;
251 }
252
SendRequest(UdmfServiceInterfaceCode code,MessageParcel & data,MessageParcel & reply,MessageOption & option)253 int32_t UdmfServiceProxy::SendRequest(UdmfServiceInterfaceCode code, MessageParcel &data,
254 MessageParcel &reply, MessageOption &option)
255 {
256 sptr<IRemoteObject> remote = Remote();
257 if (remote == nullptr) {
258 return E_IPC;
259 }
260 int err = remote->SendRequest(static_cast<uint32_t>(code), data, reply, option);
261 LOG_DEBUG(UDMF_SERVICE, "err: %{public}d", err);
262 return err;
263 }
264 } // namespace UDMF
265 } // namespace OHOS