|
5 | 5 | #include "messageport.h"
|
6 | 6 |
|
7 | 7 | #include <bundle.h>
|
8 |
| -#include <flutter/standard_message_codec.h> |
9 | 8 |
|
10 | 9 | #include <cstdint>
|
11 | 10 | #include <vector>
|
12 | 11 |
|
13 | 12 | #include "log.h"
|
14 | 13 |
|
15 |
| -MessagePortManager::MessagePortManager() {} |
16 |
| - |
17 |
| -MessagePortManager::~MessagePortManager() { |
18 |
| - for (const auto& [port, sink] : sinks_) { |
19 |
| - int ret; |
20 |
| - bool is_trusted = trusted_ports_.find(port) != trusted_ports_.end(); |
21 |
| - if (is_trusted) { |
22 |
| - ret = message_port_unregister_trusted_local_port(port); |
23 |
| - } else { |
24 |
| - ret = message_port_unregister_local_port(port); |
25 |
| - } |
26 |
| - if (MESSAGE_PORT_ERROR_NONE != ret) { |
27 |
| - LOG_ERROR("Failed to unregister port: %s", get_error_message(ret)); |
28 |
| - } |
| 14 | +void LocalPort::OnMessageReceived(int local_port_id, const char* remote_app_id, |
| 15 | + const char* remote_port, |
| 16 | + bool trusted_remote_port, bundle* bundle, |
| 17 | + void* user_data) { |
| 18 | + LocalPort* self = static_cast<LocalPort*>(user_data); |
| 19 | + uint8_t* byte_array = nullptr; |
| 20 | + size_t size = 0; |
| 21 | + int ret = bundle_get_byte(bundle, "bytes", |
| 22 | + reinterpret_cast<void**>(&byte_array), &size); |
| 23 | + if (ret != BUNDLE_ERROR_NONE) { |
| 24 | + Message message{ |
| 25 | + error : "Failed to get data from bundle", |
| 26 | + }; |
| 27 | + self->message_callback_(message); |
| 28 | + } else if (remote_port) { |
| 29 | + Message message{ |
| 30 | + remote_port : |
| 31 | + RemotePort{remote_app_id ? remote_app_id : "", |
| 32 | + remote_port ? remote_port : "", trusted_remote_port}, |
| 33 | + encoded_message : std::vector<uint8_t>(byte_array, byte_array + size) |
| 34 | + }; |
| 35 | + self->message_callback_(message); |
| 36 | + } else { |
| 37 | + Message message{ |
| 38 | + encoded_message : std::vector<uint8_t>(byte_array, byte_array + size) |
| 39 | + }; |
| 40 | + self->message_callback_(message); |
29 | 41 | }
|
30 | 42 | }
|
31 | 43 |
|
32 |
| -static bool ConvertEncodableValueToBundle(flutter::EncodableValue& value, |
33 |
| - bundle* bundle) { |
34 |
| - if (!bundle) { |
35 |
| - LOG_ERROR("Invalid bundle handle"); |
36 |
| - return false; |
| 44 | +LocalPort::~LocalPort() { |
| 45 | + if (port_ != -1) { |
| 46 | + Unregister(); |
37 | 47 | }
|
38 |
| - std::unique_ptr<std::vector<uint8_t>> encoded = |
39 |
| - flutter::StandardMessageCodec::GetInstance().EncodeMessage(value); |
40 |
| - |
41 |
| - int ret = bundle_add_byte(bundle, "bytes", encoded->data(), encoded->size()); |
42 |
| - if (BUNDLE_ERROR_NONE != ret) { |
43 |
| - return false; |
44 |
| - } |
45 |
| - return true; |
46 | 48 | }
|
47 | 49 |
|
48 |
| -void MessagePortManager::OnMessageReceived(int local_port_id, |
49 |
| - const char* remote_app_id, |
50 |
| - const char* remote_port, |
51 |
| - bool trusted_remote_port, |
52 |
| - bundle* message, void* user_data) { |
53 |
| - LOG_DEBUG( |
54 |
| - "OnMessageReceived, local_port_id: %d, remote_app_id: %s, " |
55 |
| - "remote_port: %s, trusted: %s", |
56 |
| - local_port_id, remote_app_id, remote_port, |
57 |
| - trusted_remote_port ? "yes" : "no"); |
58 |
| - |
59 |
| - MessagePortManager* manager = static_cast<MessagePortManager*>(user_data); |
60 |
| - |
61 |
| - if (manager->sinks_.find(local_port_id) != manager->sinks_.end()) { |
62 |
| - uint8_t* byte_array = NULL; |
63 |
| - size_t size = 0; |
64 |
| - |
65 |
| - int ret = bundle_get_byte(message, "bytes", (void**)&byte_array, &size); |
66 |
| - if (ret != BUNDLE_ERROR_NONE) { |
67 |
| - manager->sinks_[local_port_id]->Error("Failed to parse a response"); |
68 |
| - } |
69 |
| - |
70 |
| - std::vector<uint8_t> encoded(byte_array, byte_array + size); |
71 |
| - |
72 |
| - auto value = |
73 |
| - flutter::StandardMessageCodec::GetInstance().DecodeMessage(encoded); |
74 |
| - |
75 |
| - flutter::EncodableMap map; |
76 |
| - map[flutter::EncodableValue("message")] = *(value.get()); |
77 |
| - if (remote_port) { |
78 |
| - map[flutter::EncodableValue("remotePort")] = |
79 |
| - flutter::EncodableValue(std::string(remote_port)); |
80 |
| - } |
81 |
| - map[flutter::EncodableValue("remoteAppId")] = |
82 |
| - flutter::EncodableValue(remote_app_id); |
83 |
| - |
84 |
| - map[flutter::EncodableValue("trusted")] = |
85 |
| - flutter::EncodableValue(trusted_remote_port); |
86 |
| - |
87 |
| - manager->sinks_[local_port_id]->Success(flutter::EncodableValue(map)); |
88 |
| - } |
89 |
| -} |
90 |
| - |
91 |
| -MessagePortResult MessagePortManager::RegisterLocalPort( |
92 |
| - const std::string& port_name, EventSink sink, bool is_trusted, |
93 |
| - int* local_port) { |
94 |
| - LOG_DEBUG("RegisterLocalPort: %s, is_trusted: %s", port_name.c_str(), |
95 |
| - is_trusted ? "yes" : "no"); |
| 50 | +std::optional<MessagePortError> LocalPort::Register( |
| 51 | + OnMessage message_callback) { |
96 | 52 | int ret = -1;
|
97 |
| - if (is_trusted) { |
98 |
| - ret = message_port_register_trusted_local_port(port_name.c_str(), |
| 53 | + if (is_trusted_) { |
| 54 | + ret = message_port_register_trusted_local_port(name_.c_str(), |
99 | 55 | OnMessageReceived, this);
|
| 56 | + if (ret < MESSAGE_PORT_ERROR_NONE) { |
| 57 | + return MessagePortError(ret); |
| 58 | + } |
| 59 | + port_ = ret; |
100 | 60 | } else {
|
101 |
| - ret = message_port_register_local_port(port_name.c_str(), OnMessageReceived, |
| 61 | + ret = message_port_register_local_port(name_.c_str(), OnMessageReceived, |
102 | 62 | this);
|
| 63 | + if (ret < MESSAGE_PORT_ERROR_NONE) { |
| 64 | + return MessagePortError(ret); |
| 65 | + } |
| 66 | + port_ = ret; |
103 | 67 | }
|
104 | 68 |
|
105 |
| - if (ret < 0) { |
106 |
| - return CreateResult(ret); |
107 |
| - } |
108 |
| - |
109 |
| - *local_port = ret; |
110 |
| - LOG_DEBUG("Successfully opened local %s port, native id: %d", |
111 |
| - port_name.c_str(), *local_port); |
112 |
| - |
113 |
| - sinks_[*local_port] = std::move(sink); |
114 |
| - |
115 |
| - if (is_trusted) { |
116 |
| - trusted_ports_.insert(*local_port); |
117 |
| - } |
118 |
| - |
119 |
| - return CreateResult(MESSAGE_PORT_ERROR_NONE); |
| 69 | + message_callback_ = std::move(message_callback); |
| 70 | + return std::nullopt; |
120 | 71 | }
|
121 | 72 |
|
122 |
| -MessagePortResult MessagePortManager::UnregisterLocalPort(int local_port_id) { |
123 |
| - LOG_DEBUG("UnregisterLocalPort: %d", local_port_id); |
124 |
| - bool is_trusted = trusted_ports_.find(local_port_id) != trusted_ports_.end(); |
125 |
| - int ret = -1; |
126 |
| - |
127 |
| - if (is_trusted) { |
128 |
| - ret = message_port_unregister_trusted_local_port(local_port_id); |
| 73 | +std::optional<MessagePortError> LocalPort::Unregister() { |
| 74 | + if (is_trusted_) { |
| 75 | + int ret = message_port_unregister_trusted_local_port(port_); |
| 76 | + if (ret != MESSAGE_PORT_ERROR_NONE) { |
| 77 | + return MessagePortError(ret); |
| 78 | + } |
129 | 79 | } else {
|
130 |
| - ret = message_port_unregister_local_port(local_port_id); |
131 |
| - } |
132 |
| - |
133 |
| - if (MESSAGE_PORT_ERROR_NONE == ret) { |
134 |
| - sinks_.erase(local_port_id); |
135 |
| - if (is_trusted) { |
136 |
| - trusted_ports_.erase(local_port_id); |
| 80 | + int ret = message_port_unregister_local_port(port_); |
| 81 | + if (ret != MESSAGE_PORT_ERROR_NONE) { |
| 82 | + return MessagePortError(ret); |
137 | 83 | }
|
138 | 84 | }
|
139 |
| - |
140 |
| - return CreateResult(ret); |
| 85 | + port_ = -1; |
| 86 | + return std::nullopt; |
141 | 87 | }
|
142 | 88 |
|
143 |
| -MessagePortResult MessagePortManager::CheckRemotePort( |
144 |
| - std::string& remote_app_id, std::string& port_name, bool is_trusted, |
145 |
| - bool* port_check) { |
146 |
| - LOG_DEBUG("CheckRemotePort remote_app_id: %s, port_name: %s, trusted: %s", |
147 |
| - remote_app_id.c_str(), port_name.c_str(), |
148 |
| - is_trusted ? "yes" : "no"); |
149 |
| - |
150 |
| - int ret; |
151 |
| - if (is_trusted) { |
152 |
| - ret = message_port_check_trusted_remote_port(remote_app_id.c_str(), |
153 |
| - port_name.c_str(), port_check); |
| 89 | +ErrorOr<bool> RemotePort::CheckRemotePort() { |
| 90 | + bool exist = false; |
| 91 | + if (is_trusted_) { |
| 92 | + int ret = message_port_check_trusted_remote_port(app_id_.c_str(), |
| 93 | + name_.c_str(), &exist); |
| 94 | + if (ret != MESSAGE_PORT_ERROR_NONE) { |
| 95 | + return MessagePortError(ret); |
| 96 | + } |
154 | 97 | } else {
|
155 |
| - ret = message_port_check_remote_port(remote_app_id.c_str(), |
156 |
| - port_name.c_str(), port_check); |
| 98 | + int ret = |
| 99 | + message_port_check_remote_port(app_id_.c_str(), name_.c_str(), &exist); |
| 100 | + if (ret != MESSAGE_PORT_ERROR_NONE) { |
| 101 | + return MessagePortError(ret); |
| 102 | + } |
157 | 103 | }
|
158 | 104 |
|
159 |
| - LOG_DEBUG("message_port_check_%s_remote_port (%s): %s", |
160 |
| - is_trusted ? "trusted" : "", port_name.c_str(), |
161 |
| - *port_check ? "true" : "false"); |
162 |
| - |
163 |
| - return CreateResult(ret); |
| 105 | + return exist; |
164 | 106 | }
|
165 | 107 |
|
166 |
| -MessagePortResult MessagePortManager::Send(std::string& remote_app_id, |
167 |
| - std::string& port_name, |
168 |
| - flutter::EncodableValue& message, |
169 |
| - bool is_trusted) { |
170 |
| - LOG_DEBUG("Send (%s, %s), trusted: %s", remote_app_id.c_str(), |
171 |
| - port_name.c_str(), is_trusted ? "yes" : "no"); |
172 |
| - bundle* bundle = nullptr; |
173 |
| - MessagePortResult result = PrepareBundle(message, bundle); |
174 |
| - if (!result) { |
175 |
| - return result; |
| 108 | +std::optional<MessagePortError> RemotePort::Send( |
| 109 | + const std::vector<uint8_t>& encoded_message) { |
| 110 | + ErrorOr<bundle*> maybe_bundle = PrepareBundle(encoded_message); |
| 111 | + if (maybe_bundle.has_error()) { |
| 112 | + return maybe_bundle.error(); |
176 | 113 | }
|
| 114 | + bundle* bundle = maybe_bundle.value(); |
177 | 115 |
|
178 |
| - int ret; |
179 |
| - if (is_trusted) { |
180 |
| - ret = message_port_send_trusted_message(remote_app_id.c_str(), |
181 |
| - port_name.c_str(), bundle); |
| 116 | + int ret = MESSAGE_PORT_ERROR_NONE; |
| 117 | + if (is_trusted_) { |
| 118 | + ret = message_port_send_trusted_message(app_id_.c_str(), name_.c_str(), |
| 119 | + bundle); |
182 | 120 | } else {
|
183 |
| - ret = message_port_send_message(remote_app_id.c_str(), port_name.c_str(), |
184 |
| - bundle); |
| 121 | + ret = message_port_send_message(app_id_.c_str(), name_.c_str(), bundle); |
185 | 122 | }
|
186 | 123 | bundle_free(bundle);
|
187 | 124 |
|
188 |
| - return CreateResult(ret); |
| 125 | + if (ret != MESSAGE_PORT_ERROR_NONE) { |
| 126 | + return MessagePortError(ret); |
| 127 | + } |
| 128 | + |
| 129 | + return std::nullopt; |
189 | 130 | }
|
190 | 131 |
|
191 |
| -MessagePortResult MessagePortManager::Send(std::string& remote_app_id, |
192 |
| - std::string& port_name, |
193 |
| - flutter::EncodableValue& message, |
194 |
| - bool is_trusted, int local_port) { |
195 |
| - LOG_DEBUG("Send (%s, %s), port: %d, trusted: %s", remote_app_id.c_str(), |
196 |
| - port_name.c_str(), local_port, is_trusted ? "yes" : "no"); |
197 |
| - bundle* bundle = nullptr; |
198 |
| - MessagePortResult result = PrepareBundle(message, bundle); |
199 |
| - if (!result) { |
200 |
| - return result; |
| 132 | +std::optional<MessagePortError> RemotePort::SendWithLocalPort( |
| 133 | + const std::vector<uint8_t>& encoded_message, LocalPort* local_port) { |
| 134 | + ErrorOr<bundle*> maybe_bundle = PrepareBundle(encoded_message); |
| 135 | + if (maybe_bundle.has_error()) { |
| 136 | + return maybe_bundle.error(); |
201 | 137 | }
|
202 |
| - int ret; |
203 |
| - if (is_trusted) { |
| 138 | + bundle* bundle = maybe_bundle.value(); |
| 139 | + |
| 140 | + int ret = MESSAGE_PORT_ERROR_NONE; |
| 141 | + if (is_trusted_) { |
204 | 142 | ret = message_port_send_trusted_message_with_local_port(
|
205 |
| - remote_app_id.c_str(), port_name.c_str(), bundle, local_port); |
| 143 | + app_id_.c_str(), name_.c_str(), bundle, local_port->port()); |
206 | 144 | } else {
|
207 | 145 | ret = message_port_send_message_with_local_port(
|
208 |
| - remote_app_id.c_str(), port_name.c_str(), bundle, local_port); |
| 146 | + app_id_.c_str(), name_.c_str(), bundle, local_port->port()); |
209 | 147 | }
|
210 | 148 | bundle_free(bundle);
|
211 | 149 |
|
212 |
| - return CreateResult(ret); |
| 150 | + if (ret != MESSAGE_PORT_ERROR_NONE) { |
| 151 | + return MessagePortError(ret); |
| 152 | + } |
| 153 | + |
| 154 | + return std::nullopt; |
213 | 155 | }
|
214 | 156 |
|
215 |
| -MessagePortResult MessagePortManager::PrepareBundle( |
216 |
| - flutter::EncodableValue& message, bundle*& bundle) { |
217 |
| - bundle = bundle_create(); |
| 157 | +ErrorOr<bundle*> RemotePort::PrepareBundle( |
| 158 | + const std::vector<uint8_t>& encoded_message) { |
| 159 | + bundle* bundle = bundle_create(); |
218 | 160 | if (!bundle) {
|
219 |
| - return CreateResult(MESSAGE_PORT_ERROR_OUT_OF_MEMORY); |
| 161 | + return MessagePortError(MESSAGE_PORT_ERROR_OUT_OF_MEMORY); |
220 | 162 | }
|
221 | 163 |
|
222 |
| - bool result = ConvertEncodableValueToBundle(message, bundle); |
223 |
| - if (!result) { |
224 |
| - LOG_ERROR("Failed to parse EncodableValue"); |
| 164 | + int ret = bundle_add_byte(bundle, "bytes", encoded_message.data(), |
| 165 | + encoded_message.size()); |
| 166 | + if (ret != BUNDLE_ERROR_NONE) { |
225 | 167 | bundle_free(bundle);
|
226 |
| - return CreateResult(MESSAGE_PORT_ERROR_INVALID_PARAMETER); |
| 168 | + return MessagePortError(ret); |
227 | 169 | }
|
228 |
| - return CreateResult(MESSAGE_PORT_ERROR_NONE); |
229 |
| -} |
230 | 170 |
|
231 |
| -MessagePortResult MessagePortManager::CreateResult(int return_code) { |
232 |
| - MessagePortResult result(return_code); |
233 |
| - |
234 |
| - if (!result) { |
235 |
| - LOG_ERROR("Failed: %s", result.message().c_str()); |
236 |
| - } |
237 |
| - return result; |
| 171 | + return bundle; |
238 | 172 | }
|
0 commit comments