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 "data_proxy_observer_stub.h"
17
18 #include "dataproxy_handle_common.h"
19 #include "datashare_itypes_utils.h"
20 #include "datashare_log.h"
21
22 namespace OHOS {
23 namespace DataShare {
24 static constexpr int MAX_VEC_SIZE = 1024;
25 static constexpr int REQUEST_CODE = 0;
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)26 int RdbObserverStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
27 {
28 std::u16string descriptor = RdbObserverStub::GetDescriptor();
29 std::u16string remoteDescriptor = data.ReadInterfaceToken();
30 if (descriptor != remoteDescriptor) {
31 LOG_ERROR("local descriptor is not equal to remote");
32 return ERR_INVALID_STATE;
33 }
34 if (code != REQUEST_CODE) {
35 LOG_ERROR("not support code:%u", code);
36 return ERR_INVALID_STATE;
37 }
38 RdbChangeNode changeNode;
39 if (!ITypesUtil::Unmarshal(data, changeNode)) {
40 LOG_ERROR("Unmarshalling is nullptr");
41 return ERR_INVALID_VALUE;
42 }
43 OnChangeFromRdb(changeNode);
44 return ERR_OK;
45 }
46
ReadAshmem(RdbChangeNode & changeNode,const void ** data,int size,int & offset)47 int RdbObserverStub::ReadAshmem(RdbChangeNode &changeNode, const void **data, int size, int &offset)
48 {
49 if (changeNode.memory_ == nullptr) {
50 LOG_ERROR("changeNode memory is nullptr.");
51 return E_ERROR;
52 }
53 const void *read = changeNode.memory_->ReadFromAshmem(size, offset);
54 if (read == nullptr) {
55 LOG_ERROR("failed to read from ashmem.");
56 changeNode.memory_->UnmapAshmem();
57 changeNode.memory_->CloseAshmem();
58 changeNode.memory_ = nullptr;
59 return E_ERROR;
60 }
61 *data = read;
62 offset += size;
63 return E_OK;
64 }
65
DeserializeDataFromAshmem(RdbChangeNode & changeNode)66 int RdbObserverStub::DeserializeDataFromAshmem(RdbChangeNode &changeNode)
67 {
68 if (changeNode.memory_ == nullptr) {
69 LOG_ERROR("changeNode.memory_ is null.");
70 return E_ERROR;
71 }
72 bool mapRet = changeNode.memory_->MapReadAndWriteAshmem();
73 if (!mapRet) {
74 LOG_ERROR("failed to map read and write ashmem, ret=%{public}d", mapRet);
75 changeNode.memory_->CloseAshmem();
76 changeNode.memory_ = nullptr;
77 return E_ERROR;
78 }
79 LOG_DEBUG("receive data size: %{public}d", changeNode.size_);
80 // Read data size
81 int intLen = 4;
82 int offset = 0;
83 const int *vecLenRead;
84 if (ReadAshmem(changeNode, (const void **)&vecLenRead, intLen, offset) != E_OK) {
85 LOG_ERROR("failed to read data with len %{public}d, offset %{public}d.", intLen, offset);
86 return E_ERROR;
87 }
88 int vecLen = *vecLenRead;
89 if (vecLen > MAX_VEC_SIZE || vecLen < 0) {
90 LOG_ERROR("vecLen is invalid: %{public}d", vecLen);
91 return E_ERROR;
92 }
93 // Read data
94 for (int i = 0; i < vecLen; i++) {
95 const int *dataLenRead;
96 if (ReadAshmem(changeNode, (const void **)&dataLenRead, intLen, offset) != E_OK) {
97 LOG_ERROR(
98 "failed to read data with index %{public}d, len %{public}d, offset %{public}d.", i, intLen, offset);
99 return E_ERROR;
100 }
101 int dataLen = *dataLenRead;
102 const char *dataRead;
103 if (ReadAshmem(changeNode, (const void **)&dataRead, dataLen, offset) != E_OK) {
104 LOG_ERROR(
105 "failed to read data with index %{public}d, len %{public}d, offset %{public}d.", i, dataLen, offset);
106 return E_ERROR;
107 }
108 std::string data(dataRead, dataLen);
109 changeNode.data_.push_back(data);
110 }
111 return E_OK;
112 }
113
RecoverRdbChangeNodeData(RdbChangeNode & changeNode)114 int RdbObserverStub::RecoverRdbChangeNodeData(RdbChangeNode &changeNode)
115 {
116 int ret = E_OK;
117 if (changeNode.isSharedMemory_) {
118 // Recover form Ashmem
119 if (DeserializeDataFromAshmem(changeNode) != E_OK) {
120 LOG_ERROR("failed to deserialize data from ashmem.");
121 ret = E_ERROR;
122 }
123 if (changeNode.memory_ != nullptr) {
124 changeNode.memory_->UnmapAshmem();
125 changeNode.memory_->CloseAshmem();
126 changeNode.memory_ = nullptr;
127 }
128 changeNode.isSharedMemory_ = false;
129 changeNode.size_ = 0;
130 }
131 return ret;
132 }
133
OnChangeFromRdb(RdbChangeNode & changeNode)134 void RdbObserverStub::OnChangeFromRdb(RdbChangeNode &changeNode)
135 {
136 std::lock_guard<decltype(mutex_)> lock(mutex_);
137 if (RecoverRdbChangeNodeData(changeNode) != E_OK) {
138 LOG_ERROR("failed to recover RdbChangeNode data.");
139 return;
140 }
141 if (callback_) {
142 callback_(changeNode);
143 }
144 }
145
RdbObserverStub(RdbCallback callback)146 RdbObserverStub::RdbObserverStub(RdbCallback callback) : callback_(callback)
147 {
148 }
149
~RdbObserverStub()150 RdbObserverStub::~RdbObserverStub()
151 {
152 ClearCallback();
153 }
154
ClearCallback()155 void RdbObserverStub::ClearCallback()
156 {
157 std::lock_guard<decltype(mutex_)> lock(mutex_);
158 callback_ = nullptr;
159 }
160
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)161 int PublishedDataObserverStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
162 MessageOption &option)
163 {
164 std::u16string descriptor = PublishedDataObserverStub::GetDescriptor();
165 std::u16string remoteDescriptor = data.ReadInterfaceToken();
166 if (descriptor != remoteDescriptor) {
167 LOG_ERROR("local descriptor is not equal to remote");
168 return ERR_INVALID_STATE;
169 }
170 if (code != REQUEST_CODE) {
171 LOG_ERROR("not support code:%u", code);
172 return ERR_INVALID_STATE;
173 }
174 PublishedDataChangeNode changeNode;
175 if (!ITypesUtil::Unmarshal(data, changeNode)) {
176 LOG_ERROR("Unmarshalling is nullptr");
177 return ERR_INVALID_VALUE;
178 }
179 OnChangeFromPublishedData(changeNode);
180 return ERR_OK;
181 }
182
OnChangeFromPublishedData(PublishedDataChangeNode & changeNode)183 void PublishedDataObserverStub::OnChangeFromPublishedData(PublishedDataChangeNode &changeNode)
184 {
185 std::lock_guard<decltype(mutex_)> lock(mutex_);
186 if (callback_) {
187 callback_(changeNode);
188 }
189 }
190
ClearCallback()191 void PublishedDataObserverStub::ClearCallback()
192 {
193 std::lock_guard<decltype(mutex_)> lock(mutex_);
194 callback_ = nullptr;
195 }
196
~PublishedDataObserverStub()197 PublishedDataObserverStub::~PublishedDataObserverStub()
198 {
199 ClearCallback();
200 }
201
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)202 int ProxyDataObserverStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
203 MessageOption &option)
204 {
205 std::u16string descriptor = PublishedDataObserverStub::GetDescriptor();
206 std::u16string remoteDescriptor = data.ReadInterfaceToken();
207 if (descriptor != remoteDescriptor) {
208 LOG_ERROR("local descriptor is not equal to remote");
209 return ERR_INVALID_STATE;
210 }
211 if (code != REQUEST_CODE) {
212 LOG_ERROR("not support code:%u", code);
213 return ERR_INVALID_STATE;
214 }
215 std::vector<DataProxyChangeInfo> changeInfo;
216 if (!ITypesUtil::Unmarshal(data, changeInfo)) {
217 LOG_ERROR("Unmarshalling is nullptr");
218 return ERR_INVALID_VALUE;
219 }
220 OnChangeFromProxyData(changeInfo);
221 return ERR_OK;
222 }
223
OnChangeFromProxyData(std::vector<DataProxyChangeInfo> & changeInfo)224 void ProxyDataObserverStub::OnChangeFromProxyData(std::vector<DataProxyChangeInfo> &changeInfo)
225 {
226 std::lock_guard<decltype(mutex_)> lock(mutex_);
227 if (callback_) {
228 callback_(changeInfo);
229 }
230 }
231
ClearCallback()232 void ProxyDataObserverStub::ClearCallback()
233 {
234 std::lock_guard<decltype(mutex_)> lock(mutex_);
235 callback_ = nullptr;
236 }
237
~ProxyDataObserverStub()238 ProxyDataObserverStub::~ProxyDataObserverStub()
239 {
240 ClearCallback();
241 }
242 } // namespace DataShare
243 } // namespace OHOS
244